diff --git a/clients/tui/nmt-device-entry.c b/clients/tui/nmt-device-entry.c index d3cd9c7ba..4c5b88d11 100644 --- a/clients/tui/nmt-device-entry.c +++ b/clients/tui/nmt-device-entry.c @@ -327,7 +327,8 @@ nmt_device_entry_set_mac_address (NmtDeviceEntry *deventry, g_clear_pointer (&priv->mac_address, g_byte_array_unref); changed = TRUE; } else if ( mac_address && priv->mac_address - && memcmp (mac_address->data, priv->mac_address->data, mac_address->len) != 0) { + && !nm_utils_hwaddr_matches (mac_address->data, mac_address->len, + priv->mac_address->data, priv->mac_address->len)) { g_byte_array_unref (priv->mac_address); priv->mac_address = g_boxed_copy (DBUS_TYPE_G_UCHAR_ARRAY, mac_address); changed = TRUE; diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 48be2f585..aeb2063a3 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2113,6 +2113,94 @@ nm_utils_hwaddr_valid (const char *asc, gssize length) return nm_utils_hwaddr_aton (asc, buf, length) != NULL; } +/** + * nm_utils_hwaddr_matches: + * @hwaddr1: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr1_len: size of @hwaddr1, or -1 if @hwaddr1 is ASCII + * @hwaddr2: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr2_len: size of @hwaddr2, or -1 if @hwaddr2 is ASCII + * + * Generalized hardware address comparison function. Tests if @hwaddr1 and + * @hwaddr2 "equal" (or more precisely, "equivalent"), with several advantages + * over a simple memcmp(): + * + * 1. If @hwaddr1_len or @hwaddr2_len is -1, then the corresponding address is + * assumed to be ASCII rather than binary, and will be converted to binary + * before being compared. + * + * 2. If @hwaddr1 or @hwaddr2 is %NULL, it is treated instead as though it was + * a zero-filled buffer @hwaddr1_len or @hwaddr2_len bytes long. + * + * 3. If @hwaddr1 and @hwaddr2 are InfiniBand hardware addresses (that is, if + * they are %INFINIBAND_ALEN bytes long in binary form) then only the last + * 8 bytes are compared, since those are the only bytes that matter for + * InfiniBand hardware address matching. + * + * If a passed-in ASCII hardware address cannot be parsed, or would parse to an + * address larger than %NM_UTILS_HWADDR_LEN_MAX, then it will silently fail to + * match. (This means that externally-provided address strings do not need to be + * sanity-checked before comparing them against known good addresses; they are + * guaranteed to not match if they are invalid.) + * + * Return value: %TRUE if @hwaddr1 and @hwaddr2 are equivalent, %FALSE if they are + * different (or either of them is invalid). + */ +gboolean +nm_utils_hwaddr_matches (gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len) +{ + guint8 buf1[NM_UTILS_HWADDR_LEN_MAX], buf2[NM_UTILS_HWADDR_LEN_MAX]; + + if (hwaddr1_len == -1) { + g_return_val_if_fail (hwaddr1 != NULL, FALSE); + + hwaddr1_len = hwaddr_binary_len (hwaddr1); + if (hwaddr1_len > NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + if (!nm_utils_hwaddr_aton (hwaddr1, buf1, hwaddr1_len)) + return FALSE; + + hwaddr1 = buf1; + } else { + g_return_val_if_fail (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (!hwaddr1) { + memset (buf1, 0, hwaddr1_len); + hwaddr1 = buf1; + } + } + + if (hwaddr2_len == -1) { + g_return_val_if_fail (hwaddr2 != NULL, FALSE); + + if (!nm_utils_hwaddr_aton (hwaddr2, buf2, hwaddr1_len)) + return FALSE; + + hwaddr2 = buf2; + hwaddr2_len = hwaddr1_len; + } else { + g_return_val_if_fail (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (!hwaddr2) { + memset (buf2, 0, hwaddr2_len); + hwaddr2 = buf2; + } + } + + if (hwaddr1_len != hwaddr2_len) + return FALSE; + + if (hwaddr1_len == INFINIBAND_ALEN) { + hwaddr1 = (guint8 *)hwaddr1 + INFINIBAND_ALEN - 8; + hwaddr2 = (guint8 *)hwaddr2 + INFINIBAND_ALEN - 8; + hwaddr1_len = hwaddr2_len = 8; + } + + return !memcmp (hwaddr1, hwaddr2, hwaddr1_len); +} + /** * nm_utils_bin2hexstr: * @bytes: an array of bytes diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index dcc4aea28..e4ce9dfdb 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -146,6 +146,10 @@ GByteArray *nm_utils_hwaddr_atoba (const char *asc, gsize length); guint8 *nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length); gboolean nm_utils_hwaddr_valid (const char *asc, gssize length); +gboolean nm_utils_hwaddr_matches (gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len); char *nm_utils_bin2hexstr (const char *bytes, int len, int final_len); int nm_utils_hex2byte (const char *hex); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 30bd5629d..0f2f983a8 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -1943,6 +1943,69 @@ test_hwaddr_aton_malformed (void) g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:a@%%", buf, ETH_ALEN) == NULL); } +static void +test_hwaddr_equal (void) +{ + const char *string = "00:1a:2b:03:44:05"; + const char *upper_string = "00:1A:2B:03:44:05"; + const char *bad_string = "0:1a:2b:3:44:5"; + const guint8 binary[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 }; + const char *other_string = "1a:2b:03:44:05:00"; + const guint8 other_binary[ETH_ALEN] = { 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x00 }; + const char *long_string = "00:1a:2b:03:44:05:06:07"; + const guint8 long_binary[8] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x06, 0x07 }; + const char *null_string = "00:00:00:00:00:00"; + const guint8 null_binary[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + g_assert (nm_utils_hwaddr_matches (string, -1, string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, NULL, ETH_ALEN)); + + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_string, -1, string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), NULL, ETH_ALEN)); +} + static void test_connection_changed_cb (NMConnection *connection, gboolean *data) { @@ -2656,6 +2719,7 @@ int main (int argc, char **argv) test_hwaddr_aton_ib_normal (); test_hwaddr_aton_no_leading_zeros (); test_hwaddr_aton_malformed (); + test_hwaddr_equal (); test_ip4_prefix_to_netmask (); test_ip4_netmask_to_prefix (); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index de928410f..5203f9fe0 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -884,6 +884,7 @@ global: nm_utils_hwaddr_atoba; nm_utils_hwaddr_aton; nm_utils_hwaddr_len; + nm_utils_hwaddr_matches; nm_utils_hwaddr_ntoa; nm_utils_hwaddr_valid; nm_utils_iface_valid_name; diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c index 3bad4dee1..652cb6a89 100644 --- a/libnm/nm-access-point.c +++ b/libnm/nm-access-point.c @@ -235,11 +235,10 @@ nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - const char *ctype, *ap_bssid_str; + const char *ctype, *ap_bssid; const GByteArray *setting_ssid; const GByteArray *ap_ssid; const GByteArray *setting_bssid; - guint8 ap_bssid[ETH_ALEN]; const char *setting_mode; NM80211Mode ap_mode; const char *setting_band; @@ -265,16 +264,12 @@ nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection) return FALSE; /* BSSID checks */ - ap_bssid_str = nm_access_point_get_bssid (ap); - g_warn_if_fail (ap_bssid_str); + ap_bssid = nm_access_point_get_bssid (ap); + g_warn_if_fail (ap_bssid); setting_bssid = nm_setting_wireless_get_bssid (s_wifi); - if (setting_bssid && ap_bssid_str) { - g_assert (setting_bssid->len == ETH_ALEN); - if (nm_utils_hwaddr_aton (ap_bssid_str, ap_bssid, ETH_ALEN)) { - if (memcmp (ap_bssid, setting_bssid->data, ETH_ALEN) != 0) - return FALSE; - } else - g_warn_if_reached (); + if (setting_bssid && ap_bssid) { + if (!nm_utils_hwaddr_matches (ap_bssid, -1, setting_bssid->data, setting_bssid->len)) + return FALSE; } /* Mode */ diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c index 988811076..40fc76709 100644 --- a/libnm/nm-device-bt.c +++ b/libnm/nm-device-bt.c @@ -147,8 +147,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingBluetooth *s_bt; const char *ctype; const GByteArray *mac; - const char *hw_str; - guint8 hw_mac[ETH_ALEN]; + const char *hw_addr; NMBluetoothCapabilities dev_caps; NMBluetoothCapabilities bt_type; @@ -170,15 +169,15 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } /* Check BT address */ - hw_str = nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); - if (hw_str) { - if (!nm_utils_hwaddr_aton (hw_str, hw_mac, ETH_ALEN)) { + hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); + if (hw_addr) { + if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } mac = nm_setting_bluetooth_get_bdaddr (s_bt); - if (mac && memcmp (mac->data, hw_mac, ETH_ALEN)) { + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, hw_addr, -1)) { g_set_error (error, NM_DEVICE_BT_ERROR, NM_DEVICE_BT_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c index 4dfdcd840..65906913f 100644 --- a/libnm/nm-device-ethernet.c +++ b/libnm/nm-device-ethernet.c @@ -169,21 +169,20 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro if (s_wired) { const GByteArray *mac; - const char *perm_str; - guint8 perm_mac[ETH_ALEN]; + const char *perm_addr; /* FIXME: filter using s390 subchannels when they are exported over the bus */ /* Check MAC address */ - perm_str = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device)); - if (perm_str) { - if (!nm_utils_hwaddr_aton (perm_str, perm_mac, ETH_ALEN)) { + perm_addr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device)); + if (perm_addr) { + if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_ETHERNET_ERROR, NM_DEVICE_ETHERNET_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } mac = nm_setting_wired_get_mac_address (s_wired); - if (mac && memcmp (mac->data, perm_mac, ETH_ALEN)) { + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, perm_addr, -1)) { g_set_error (error, NM_DEVICE_ETHERNET_ERROR, NM_DEVICE_ETHERNET_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c index 1b2720b0b..970e307c0 100644 --- a/libnm/nm-device-infiniband.c +++ b/libnm/nm-device-infiniband.c @@ -105,9 +105,8 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro { NMSettingConnection *s_con; NMSettingInfiniband *s_infiniband; - const char *ctype, *hwaddr_str; + const char *ctype, *hwaddr; const GByteArray *mac; - guint8 *hwaddr, hwaddr_buf[INFINIBAND_ALEN]; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -126,18 +125,16 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - hwaddr_str = nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); - if (hwaddr_str) { - hwaddr = nm_utils_hwaddr_aton (hwaddr_str, hwaddr_buf, INFINIBAND_ALEN); - if (!hwaddr) { + hwaddr = nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid (hwaddr, INFINIBAND_ALEN)) { g_set_error (error, NM_DEVICE_INFINIBAND_ERROR, NM_DEVICE_INFINIBAND_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } mac = nm_setting_infiniband_get_mac_address (s_infiniband); - /* We only match against the last 8 bytes */ - if (mac && hwaddr && memcmp (mac->data + INFINIBAND_ALEN - 8, hwaddr + INFINIBAND_ALEN - 8, 8)) { + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, hwaddr, -1)) { g_set_error (error, NM_DEVICE_INFINIBAND_ERROR, NM_DEVICE_INFINIBAND_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c index 2cb3b5f84..d9a14efde 100644 --- a/libnm/nm-device-wifi.c +++ b/libnm/nm-device-wifi.c @@ -419,8 +419,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingWirelessSecurity *s_wsec; const char *ctype; const GByteArray *mac; - const char *hw_str; - guint8 hw_mac[ETH_ALEN]; + const char *hw_addr; NMDeviceWifiCapabilities wifi_caps; const char *key_mgmt; @@ -442,15 +441,15 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } /* Check MAC address */ - hw_str = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); - if (hw_str) { - if (!nm_utils_hwaddr_aton (hw_str, hw_mac, ETH_ALEN)) { + hw_addr = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); + if (hw_addr) { + if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } mac = nm_setting_wireless_get_mac_address (s_wifi); - if (mac && memcmp (mac->data, hw_mac, ETH_ALEN)) { + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, hw_addr, -1)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/libnm/nm-device-wimax.c b/libnm/nm-device-wimax.c index 95e17e35b..f842b83c8 100644 --- a/libnm/nm-device-wimax.c +++ b/libnm/nm-device-wimax.c @@ -323,8 +323,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingWimax *s_wimax; const char *ctype; const GByteArray *mac; - const char *hw_str; - guint8 hw_mac[ETH_ALEN]; + const char *hw_addr; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -344,15 +343,15 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } /* Check MAC address */ - hw_str = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); - if (hw_str) { - if (!nm_utils_hwaddr_aton (hw_str, hw_mac, ETH_ALEN)) { + hw_addr = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); + if (hw_addr) { + if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_WIMAX_ERROR, NM_DEVICE_WIMAX_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } mac = nm_setting_wimax_get_mac_address (s_wimax); - if (mac && memcmp (mac->data, hw_mac, ETH_ALEN)) { + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, hw_addr, -1)) { g_set_error (error, NM_DEVICE_WIMAX_ERROR, NM_DEVICE_WIMAX_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 4939b5ec0..aa689ce05 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -585,18 +585,22 @@ nm_match_spec_string (const GSList *specs, const char *match) gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) { - char *hwaddr_match; - gboolean matched; + const GSList *iter; g_return_val_if_fail (hwaddr != NULL, FALSE); - if (nm_match_spec_string (specs, hwaddr)) - return TRUE; + for (iter = specs; iter; iter = g_slist_next (iter)) { + const char *spec_str = iter->data; - hwaddr_match = g_strdup_printf ("mac:%s", hwaddr); - matched = nm_match_spec_string (specs, hwaddr_match); - g_free (hwaddr_match); - return matched; + if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) + && nm_utils_hwaddr_matches (spec_str + 4, -1, hwaddr, -1)) + return TRUE; + + if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr, -1)) + return TRUE; + } + + return FALSE; } gboolean diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 7cb2910d1..84919a9cb 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -314,9 +314,9 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection) return FALSE; } bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr || bdaddr->len != ETH_ALEN) + if (!bdaddr) return FALSE; - if (memcmp (bdaddr->data, priv->bin_address, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (bdaddr->data, bdaddr->len, priv->bin_address, ETH_ALEN)) return FALSE; bt_type = nm_setting_bluetooth_get_connection_type (s_bt); diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 114e852bf..755397bd0 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -179,10 +179,9 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; array = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!array || (array->len != ETH_ALEN)) + if (!array) return FALSE; - - if (memcmp (priv->bdaddr, array->data, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (priv->bdaddr, ETH_ALEN, array->data, array->len)) return FALSE; return TRUE; @@ -324,7 +323,7 @@ complete_connection (NMDevice *device, setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); if (setting_bdaddr) { /* Make sure the setting BT Address (if any) matches the device's */ - if (memcmp (setting_bdaddr->data, priv->bdaddr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_bdaddr->data, setting_bdaddr->len, priv->bdaddr, ETH_ALEN)) { g_set_error_literal (error, NM_SETTING_BLUETOOTH_ERROR, NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, @@ -333,10 +332,9 @@ complete_connection (NMDevice *device, } } else { GByteArray *bdaddr; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* Lock the connection to this device by default */ - if (memcmp (priv->bdaddr, null_mac, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (priv->bdaddr, ETH_ALEN, NULL, ETH_ALEN)) { bdaddr = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (bdaddr, priv->bdaddr, ETH_ALEN); g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL); diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 179abd5ed..29bd7f1a7 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -122,8 +122,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) hw_addr = nm_device_get_hw_address (device, &hw_len); if ( !hw_addr - || hw_len != mac_address->len - || memcmp (mac_address->data, hw_addr, hw_len) != 0) + || !nm_utils_hwaddr_matches (mac_address->data, mac_address->len, hw_addr, hw_len)) return FALSE; } diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index e9d9d2002..3cc5e7b5b 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -369,7 +369,7 @@ update_permanent_hw_address (NMDevice *dev) memset (epaddr->data, 0, ETH_ALEN); } - if (memcmp (priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, 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); } @@ -473,7 +473,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && mac && memcmp (mac->data, priv->perm_hw_addr, ETH_ALEN)) + if (try_mac && mac && !nm_utils_hwaddr_matches (mac->data, mac->len, priv->perm_hw_addr, ETH_ALEN)) return FALSE; /* Check for MAC address blacklist */ @@ -487,7 +487,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; } - if (memcmp (addr, priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->perm_hw_addr, ETH_ALEN)) return FALSE; } } @@ -1462,7 +1462,7 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, priv->perm_hw_addr, ETH_ALEN)) { g_set_error_literal (error, NM_SETTING_WIRED_ERROR, NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, @@ -1471,10 +1471,9 @@ complete_connection (NMDevice *device, } } else { GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* Lock the connection to this device by default */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) { mac = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); @@ -1503,7 +1502,6 @@ update_connection (NMDevice *device, NMConnection *connection) NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); guint maclen; const guint8 *mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GByteArray *array; GHashTableIter iter; @@ -1517,14 +1515,14 @@ update_connection (NMDevice *device, NMConnection *connection) /* If the device reports a permanent address, use that for the MAC address * and the current MAC, if different, is the cloned MAC. */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) { array = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (array, priv->perm_hw_addr, ETH_ALEN); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, array, NULL); g_byte_array_unref (array); mac_prop = NULL; - if (mac && memcmp (priv->perm_hw_addr, mac, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, mac, ETH_ALEN)) mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS; } diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 416ef0f82..514a36a2a 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -208,10 +208,8 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (s_infiniband) { mac = nm_setting_infiniband_get_mac_address (s_infiniband); - /* We only compare the last 8 bytes */ - if (mac && memcmp (mac->data + INFINIBAND_ALEN - 8, - nm_device_get_hw_address (device, NULL) + INFINIBAND_ALEN - 8, - 8)) + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, + nm_device_get_hw_address (device, NULL), INFINIBAND_ALEN)) return FALSE; } @@ -246,7 +244,7 @@ complete_connection (NMDevice *device, hw_address = nm_device_get_hw_address (device, NULL); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's MAC */ - if (memcmp (setting_mac->data, hw_address, INFINIBAND_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, hw_address, INFINIBAND_ALEN)) { g_set_error_literal (error, NM_SETTING_INFINIBAND_ERROR, NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY, @@ -275,7 +273,6 @@ update_connection (NMDevice *device, NMConnection *connection) NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); guint maclen; gconstpointer mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[INFINIBAND_ALEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; GByteArray *array; char *mode_path, *contents = NULL; const char *transport_mode = "datagram"; @@ -285,7 +282,7 @@ update_connection (NMDevice *device, NMConnection *connection) nm_connection_add_setting (connection, (NMSetting *) s_infiniband); } - if (mac && (maclen == INFINIBAND_ALEN) && (memcmp (mac, null_mac, maclen) != 0)) { + if (mac && !nm_utils_hwaddr_matches (mac, maclen, NULL, INFINIBAND_ALEN)) { array = g_byte_array_sized_new (maclen); g_byte_array_append (array, (guint8 *) mac, maclen); g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, array, NULL); @@ -306,37 +303,6 @@ update_connection (NMDevice *device, NMConnection *connection) g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL); } -static gboolean -spec_match_list (NMDevice *device, const GSList *specs) -{ - char *hwaddr_str, *spec_str; - const GSList *iter; - - if (NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->spec_match_list (device, specs)) - return TRUE; - - hwaddr_str = nm_utils_hwaddr_ntoa (nm_device_get_hw_address (device, NULL), INFINIBAND_ALEN); - - /* InfiniBand hardware address matches only need to match the last - * 8 bytes. In string format, that means we skip the first 36 - * characters of hwaddr_str, and the first 40 of the spec (to skip - * "mac:" too). - */ - for (iter = specs; iter; iter = g_slist_next (iter)) { - spec_str = iter->data; - - if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) - && strlen (spec_str) > 40 - && !g_ascii_strcasecmp (spec_str + 40, hwaddr_str + 36)) { - g_free (hwaddr_str); - return TRUE; - } - } - - g_free (hwaddr_str); - return FALSE; -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -375,7 +341,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; - parent_class->spec_match_list = spec_match_list; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->ip4_config_pre_commit = ip4_config_pre_commit; diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 093295396..b72b78dbd 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -171,8 +171,7 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw device_mac = nm_device_get_hw_address (device, &device_mac_len); - return ( mac->len == device_mac_len - && memcmp (mac->data, device_mac, device_mac_len) == 0); + return nm_utils_hwaddr_matches (mac->data, mac->len, device_mac, device_mac_len); } static gboolean diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 65228c663..566527085 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6953,7 +6953,7 @@ nm_device_set_hw_addr (NMDevice *self, const guint8 *addr, g_return_val_if_fail (addr != NULL, FALSE); /* Do nothing if current MAC is same */ - if (cur_addr && !memcmp (cur_addr, addr, len)) { + if (cur_addr && nm_utils_hwaddr_matches (cur_addr, len, addr, len)) { _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed"); return TRUE; } @@ -6968,7 +6968,7 @@ nm_device_set_hw_addr (NMDevice *self, const guint8 *addr, /* MAC address succesfully changed; update the current MAC to match */ nm_device_update_hw_address (self); cur_addr = nm_device_get_hw_address (self, NULL); - if (memcmp (cur_addr, addr, len) == 0) { + if (nm_utils_hwaddr_matches (cur_addr, len, addr, len)) { _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s", detail, mac_str); } else { diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 47f15e727..8bba6d386 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -349,8 +349,7 @@ check_companion (NMDeviceOlpcMesh *self, NMDevice *other) my_addr = nm_device_get_hw_address (NM_DEVICE (self), NULL); their_addr = nm_device_get_hw_address (other, &their_addr_len); - if ( (their_addr_len != ETH_ALEN) - || (memcmp (my_addr, their_addr, ETH_ALEN) != 0)) + if (!nm_utils_hwaddr_matches (my_addr, ETH_ALEN, their_addr, their_addr_len)) return FALSE; g_assert (priv->companion == NULL); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 2c8ad10f8..2a8e1870c 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -416,7 +416,7 @@ find_active_ap (NMDeviceWifi *self, continue; } - if (memcmp (bssid, ap_bssid, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (bssid, ETH_ALEN, ap_bssid, ETH_ALEN)) { _LOGD (LOGD_WIFI, " BSSID mismatch"); continue; } @@ -828,7 +828,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac && memcmp (mac->data, priv->perm_hw_addr, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, priv->perm_hw_addr, ETH_ALEN)) return FALSE; /* Check for MAC address blacklist */ @@ -839,10 +839,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!nm_utils_hwaddr_aton (mac_blacklist_iter->data, addr, ETH_ALEN)) { g_warn_if_reached (); - continue; + return FALSE; } - if (memcmp (&addr, priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->perm_hw_addr, ETH_ALEN)) return FALSE; } @@ -1120,7 +1120,7 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wireless_get_mac_address (s_wifi); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, priv->perm_hw_addr, ETH_ALEN)) { g_set_error (error, NM_SETTING_WIRELESS_ERROR, NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, @@ -1129,13 +1129,12 @@ complete_connection (NMDevice *device, } } else { GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* Lock the connection to this device by default if it uses a * permanent MAC address (ie not a 'locally administered' one) */ if ( !(priv->perm_hw_addr[0] & 0x02) - && memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + && !nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) { mac = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); @@ -2539,7 +2538,7 @@ update_permanent_hw_address (NMDevice *device) memcpy (epaddr->data, nm_device_get_hw_address (device, NULL), ETH_ALEN); } - if (memcmp (priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, ETH_ALEN, epaddr->data, ETH_ALEN)) { memcpy (priv->perm_hw_addr, epaddr->data, ETH_ALEN); g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); } diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 9743286a5..f387dacd2 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -901,7 +901,7 @@ nm_ap_set_address (NMAccessPoint *ap, const guint8 *addr) priv = NM_AP_GET_PRIVATE (ap); - if (memcmp (addr, priv->address, sizeof (priv->address))) { + if (!nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->address, sizeof (priv->address))) { memcpy (NM_AP_GET_PRIVATE (ap)->address, addr, sizeof (priv->address)); g_object_notify (G_OBJECT (ap), NM_AP_HW_ADDRESS); } @@ -1124,7 +1124,7 @@ nm_ap_check_compatible (NMAccessPoint *self, return FALSE; bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid && memcmp (bssid->data, priv->address, ETH_ALEN)) + if (bssid && !nm_utils_hwaddr_matches (bssid->data, bssid->len, priv->address, ETH_ALEN)) return FALSE; mode = nm_setting_wireless_get_mode (s_wireless); @@ -1237,7 +1237,7 @@ nm_ap_match_in_list (NMAccessPoint *find_ap, /* BSSID match */ if ( (strict_match || nm_ethernet_address_is_valid (find_addr)) && nm_ethernet_address_is_valid (list_addr) - && memcmp (list_addr, find_addr, ETH_ALEN) != 0) + && !nm_utils_hwaddr_matches (list_addr, ETH_ALEN, find_addr, ETH_ALEN)) continue; /* mode match */ diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c index 1297fb496..4ad998678 100644 --- a/src/devices/wimax/nm-device-wimax.c +++ b/src/devices/wimax/nm-device-wimax.c @@ -332,7 +332,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wimax_get_mac_address (s_wimax); - if (mac && memcmp (mac->data, nm_device_get_hw_address (device, NULL), ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac->data, mac->len, nm_device_get_hw_address (device, NULL), ETH_ALEN)) return FALSE; return TRUE; @@ -452,7 +452,7 @@ complete_connection (NMDevice *device, hw_address = nm_device_get_hw_address (device, NULL); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, hw_address, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, hw_address, ETH_ALEN)) { g_set_error (error, NM_SETTING_WIMAX_ERROR, NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, @@ -461,10 +461,9 @@ complete_connection (NMDevice *device, } } else { GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* Lock the connection to this device by default */ - if (memcmp (hw_address, null_mac, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (hw_address, ETH_ALEN, NULL, ETH_ALEN)) { mac = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac, hw_address, ETH_ALEN); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL); diff --git a/src/nm-manager.c b/src/nm-manager.c index fc0db16c0..34048b789 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -856,8 +856,7 @@ get_device_from_hwaddr (NMManager *self, const GByteArray *setting_mac) NMDevice *device = iter->data; device_mac = nm_device_get_hw_address (iter->data, &device_mac_len); - if ( setting_mac->len == device_mac_len - && memcmp (setting_mac->data, device_mac, device_mac_len) == 0) + if (nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, device_mac, device_mac_len)) return device; } return NULL; diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index c88f82206..a9b2a829c 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1508,8 +1508,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* A connection mac-locked to this device */ - if (hwaddr_len == setting_mac->len && - !memcmp (setting_mac->data, hwaddr, hwaddr_len)) + if (nm_utils_hwaddr_matches (setting_mac->data, setting_mac->len, hwaddr, hwaddr_len)) return TRUE; } else { /* A connection that applies to any wired device */ diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index ee3c43244..a48290661 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -440,7 +440,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg, continue; } - if (memcmp (ifcfg_mac->data, ibft_mac, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (ibft_mac, ETH_ALEN, ifcfg_mac->data, ifcfg_mac->len)) { /* This record isn't for the current device, ignore it */ skip = TRUE; continue;