diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 1ca88d553d..f03dd1e59c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -7457,53 +7457,6 @@ get_dhcp_timeout (NMDevice *self, int addr_family) return timeout ?: NM_DHCP_TIMEOUT_DEFAULT; } -static void -_ASSERT_arp_type (guint16 arp_type, - const guint8 *hwaddr, - gsize hwaddr_len) -{ - /* we actually only support ethernet and infiniband below. Assert that - * the arp-type and the address length correspond. */ - nm_assert (NM_IN_SET (arp_type, ARPHRD_ETHER, ARPHRD_INFINIBAND)); - nm_assert (arp_type <= 255); - nm_assert (hwaddr_len > 0); - nm_assert (arp_type != ARPHRD_ETHER || hwaddr_len == ETH_ALEN); - nm_assert (arp_type != ARPHRD_INFINIBAND || hwaddr_len == INFINIBAND_ALEN); - nm_assert (hwaddr); -} - -static void -_hwaddr_get_relevant_part (guint16 arp_type, - const guint8 **hwaddr, - gsize *hwaddr_len) -{ - nm_assert (hwaddr); - nm_assert (hwaddr_len); - _ASSERT_arp_type (arp_type, *hwaddr, *hwaddr_len); - - /* for infiniband, we only consider the last 8 bytes. */ - if (arp_type == ARPHRD_INFINIBAND) { - *hwaddr += (INFINIBAND_ALEN - 8); - *hwaddr_len = 8; - } -} - -static GBytes * -dhcp4_get_client_id_mac (guint16 arp_type, - const guint8 *hwaddr, - gsize hwaddr_len) -{ - guint8 *client_id_buf; - const guint8 hwaddr_type = arp_type; - - _hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len); - - client_id_buf = g_malloc (hwaddr_len + 1); - client_id_buf[0] = hwaddr_type; - memcpy (&client_id_buf[1], hwaddr, hwaddr_len); - return g_bytes_new_take (client_id_buf, hwaddr_len + 1); -} - static GBytes * dhcp4_get_client_id (NMDevice *self, NMConnection *connection, @@ -7553,7 +7506,7 @@ dhcp4_get_client_id (NMDevice *self, goto out_fail; } - result = dhcp4_get_client_id_mac ((guint16) arp_type, hwaddr_bin, hwaddr_len); + result = nm_utils_dhcp_client_id_mac (arp_type, hwaddr_bin, hwaddr_len); goto out_good; } @@ -7575,7 +7528,7 @@ dhcp4_get_client_id (NMDevice *self, goto out_fail; } - result = dhcp4_get_client_id_mac ((guint16) arp_type, hwaddr_bin_buf, hwaddr_len); + result = nm_utils_dhcp_client_id_mac (arp_type, hwaddr_bin_buf, hwaddr_len); goto out_good; } @@ -8230,7 +8183,7 @@ dhcp6_prefix_delegated (NMDhcpClient *client, #define EPOCH_DATETIME_200001010000 946684800 static GBytes * -generate_duid_llt (guint16 arp_type, +generate_duid_llt (int arp_type, const guint8 *hwaddr, gsize hwaddr_len, gint64 time) @@ -8240,7 +8193,8 @@ generate_duid_llt (guint16 arp_type, const guint16 hw_type = htons (arp_type); const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000)); - _hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len); + if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) + nm_assert_not_reached (); arr = g_new (guint8, 2 + 2 + 4 + hwaddr_len); @@ -8253,7 +8207,7 @@ generate_duid_llt (guint16 arp_type, } static GBytes * -generate_duid_ll (guint16 arp_type, +generate_duid_ll (int arp_type, const guint8 *hwaddr, gsize hwaddr_len) { @@ -8261,7 +8215,8 @@ generate_duid_ll (guint16 arp_type, const guint16 duid_type = htons (3); const guint16 hw_type = htons (arp_type); - _hwaddr_get_relevant_part (arp_type, &hwaddr, &hwaddr_len); + if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) + nm_assert_not_reached (); arr = g_new (guint8, 2 + 2 + hwaddr_len); diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index d039a98351..89f8f329f8 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2867,6 +2867,51 @@ nm_utils_arp_type_detect_from_hwaddrlen (gsize hwaddr_len) } } +gboolean +nm_utils_arp_type_validate_hwaddr (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len) +{ + + if (!hwaddr) + return FALSE; + + if (arp_type == ARPHRD_ETHER) { + G_STATIC_ASSERT (ARPHRD_ETHER >= 0 && ARPHRD_ETHER <= 0xFF); + if (hwaddr_len != ETH_ALEN) + return FALSE; + } else if (arp_type == ARPHRD_INFINIBAND) { + G_STATIC_ASSERT (ARPHRD_INFINIBAND >= 0 && ARPHRD_INFINIBAND <= 0xFF); + if (hwaddr_len != INFINIBAND_ALEN) + return FALSE; + } else + return FALSE; + + nm_assert (arp_type == nm_utils_arp_type_detect_from_hwaddrlen (hwaddr_len)); + return TRUE; +} + +gboolean +nm_utils_arp_type_get_hwaddr_relevant_part (int arp_type, + const guint8 **hwaddr, + gsize *hwaddr_len) +{ + g_return_val_if_fail ( hwaddr + && hwaddr_len + && nm_utils_arp_type_validate_hwaddr (arp_type, *hwaddr, *hwaddr_len), + FALSE); + + /* for infiniband, we only consider the last 8 bytes. */ + if (arp_type == ARPHRD_INFINIBAND) { + *hwaddr += (INFINIBAND_ALEN - 8); + *hwaddr_len = 8; + } + + return TRUE; +} + +/*****************************************************************************/ + /* Returns the "u" (universal/local) bit value for a Modified EUI-64 */ static gboolean get_gre_eui64_u_bit (guint32 addr) @@ -3514,6 +3559,23 @@ nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type, /*****************************************************************************/ +GBytes * +nm_utils_dhcp_client_id_mac (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len) +{ + guint8 *client_id_buf; + const guint8 hwaddr_type = arp_type; + + if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) + g_return_val_if_reached (NULL); + + client_id_buf = g_malloc (hwaddr_len + 1); + client_id_buf[0] = hwaddr_type; + memcpy (&client_id_buf[1], hwaddr, hwaddr_len); + return g_bytes_new_take (client_id_buf, hwaddr_len + 1); +} + #define HASH_KEY ((const guint8[16]) { 0x80, 0x11, 0x8c, 0xc2, 0xfe, 0x4a, 0x03, 0xee, 0x3e, 0xd6, 0x0c, 0x6f, 0x36, 0x39, 0x14, 0x09 }) /** diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index f0e0c4d2ec..a93854a465 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -279,8 +279,20 @@ gboolean nm_utils_host_id_get (const guint8 **out_host_id, gsize *out_host_id_len); gint64 nm_utils_host_id_get_timestamp_ns (void); +/*****************************************************************************/ + int nm_utils_arp_type_detect_from_hwaddrlen (gsize hwaddr_len); +gboolean nm_utils_arp_type_validate_hwaddr (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len); + +gboolean nm_utils_arp_type_get_hwaddr_relevant_part (int arp_type, + const guint8 **hwaddr, + gsize *hwaddr_len); + +/*****************************************************************************/ + /* IPv6 Interface Identifier helpers */ /** @@ -375,6 +387,10 @@ char *nm_utils_hw_addr_gen_stable_eth (NMUtilsStableType stable_type, /*****************************************************************************/ +GBytes *nm_utils_dhcp_client_id_mac (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len); + guint32 nm_utils_create_dhcp_iaid (gboolean legacy_unstable_byteorder, const guint8 *interface_id, gsize interface_id_len);