mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-11 06:20:16 +01:00
dhcp: add nm_dhcp_utils_client_id_string_to_bytes()
Generic function to convert a DHCP client identifier string in either
hex form ("aa:bb:cc") or string form ("blahblah") to bytes.
This commit is contained in:
parent
cd12e97620
commit
3c34f1d92f
4 changed files with 110 additions and 6 deletions
|
|
@ -692,3 +692,68 @@ nm_dhcp_utils_duid_to_string (const GByteArray *duid)
|
|||
return g_string_free (s, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_dhcp_utils_client_id_string_to_bytes:
|
||||
* @client_id: the client ID string
|
||||
*
|
||||
* Accepts either a hex string ("aa:bb:cc") representing a binary client ID
|
||||
* (the first byte is assumed to be the 'type' field per RFC 2132 section 9.14),
|
||||
* or a string representing a non-hardware-address client ID, in which case
|
||||
* the 'type' field is set to 0.
|
||||
*
|
||||
* Returns: the binary client ID suitable for sending over the wire
|
||||
* to the DHCP server.
|
||||
*/
|
||||
GBytes *
|
||||
nm_dhcp_utils_client_id_string_to_bytes (const char *client_id)
|
||||
{
|
||||
GBytes *bytes = NULL;
|
||||
guint i = 0, x = 0;
|
||||
guint len;
|
||||
char *c;
|
||||
int a;
|
||||
|
||||
g_return_val_if_fail (client_id && client_id[0], NULL);
|
||||
|
||||
/* Accept a binary client ID in hex digits with the ':' delimiter,
|
||||
* otherwise treat it as a string.
|
||||
*/
|
||||
len = strlen (client_id);
|
||||
c = g_malloc0 (len / 2 + 1);
|
||||
while (client_id[i]) {
|
||||
a = g_ascii_xdigit_value (client_id[i++]);
|
||||
if (a >= 0) {
|
||||
if (client_id[i] != ':') {
|
||||
c[x] = ((guint8) a << 4);
|
||||
a = g_ascii_xdigit_value (client_id[i++]);
|
||||
}
|
||||
if (a >= 0)
|
||||
c[x++] |= (guint8) a;
|
||||
}
|
||||
if (client_id[i]) {
|
||||
if (client_id[i] != ':' || !client_id[i + 1]) {
|
||||
/* missing or trailing ':' is invalid for hex-format */
|
||||
a = -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (a < 0) {
|
||||
g_clear_pointer (&c, g_free);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
g_assert (x > 0);
|
||||
bytes = g_bytes_new_take (c, x);
|
||||
} else {
|
||||
c = g_malloc (len + 1);
|
||||
c[0] = 0; /* type: non-hardware address per RFC 2132 section 9.14 */
|
||||
memcpy (c + 1, client_id, len);
|
||||
bytes = g_bytes_new_take (c, len + 1);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,5 +35,7 @@ NMIP6Config *nm_dhcp_utils_ip6_config_from_options (const char *iface,
|
|||
|
||||
char * nm_dhcp_utils_duid_to_string (const GByteArray *duid);
|
||||
|
||||
GBytes * nm_dhcp_utils_client_id_string_to_bytes (const char *client_id);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DHCP_UTILS_H__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ AM_CPPFLAGS = \
|
|||
|
||||
noinst_PROGRAMS = \
|
||||
test-dhcp-dhclient \
|
||||
test-dhcp-options
|
||||
test-dhcp-utils
|
||||
|
||||
####### dhclient leases test #######
|
||||
|
||||
|
|
@ -23,17 +23,17 @@ test_dhcp_dhclient_SOURCES = \
|
|||
test_dhcp_dhclient_LDADD = \
|
||||
$(top_builddir)/src/libNetworkManager.la
|
||||
|
||||
####### DHCP options test #######
|
||||
####### DHCP utils test #######
|
||||
|
||||
test_dhcp_options_SOURCES = \
|
||||
test-dhcp-options.c
|
||||
test_dhcp_utils_SOURCES = \
|
||||
test-dhcp-utils.c
|
||||
|
||||
test_dhcp_options_LDADD = \
|
||||
test_dhcp_utils_LDADD = \
|
||||
$(top_builddir)/src/libNetworkManager.la
|
||||
|
||||
#################################
|
||||
|
||||
TESTS = test-dhcp-dhclient test-dhcp-options
|
||||
TESTS = test-dhcp-dhclient test-dhcp-utils
|
||||
|
||||
EXTRA_DIST = \
|
||||
test-dhclient-duid.leases \
|
||||
|
|
|
|||
|
|
@ -652,6 +652,42 @@ test_ip4_prefix_classless (void)
|
|||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
#define COMPARE_ID(src, is_str, expected, expected_len) \
|
||||
G_STMT_START { \
|
||||
gs_unref_bytes GBytes *b = NULL; \
|
||||
gconstpointer p; \
|
||||
gsize l; \
|
||||
\
|
||||
b = nm_dhcp_utils_client_id_string_to_bytes (src); \
|
||||
g_assert (b); \
|
||||
p = g_bytes_get_data (b, &l); \
|
||||
if (is_str) { \
|
||||
g_assert_cmpint (l, ==, expected_len + 1); \
|
||||
g_assert_cmpint (((const char *) p)[0], ==, 0); \
|
||||
g_assert (memcmp (p + 1, expected, expected_len) == 0); \
|
||||
} else { \
|
||||
g_assert_cmpint (l, ==, expected_len); \
|
||||
g_assert (memcmp (p, expected, expected_len) == 0); \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
static void
|
||||
test_client_id_from_string (void)
|
||||
{
|
||||
const char *nothex = "asdfasdfasdfasdfasdfasdfasdf";
|
||||
const char *allhex = "00:11:22:33:4:55:66:77:88";
|
||||
const guint8 allhex_bin[] = { 0x00, 0x11, 0x22, 0x33, 0x04, 0x55, 0x66, 0x77, 0x88 };
|
||||
const char *somehex = "00:11:22:33:44:55:asdfasdfasdf:99:10";
|
||||
const char *nocolons = "0011223344559910";
|
||||
const char *endcolon = "00:11:22:33:44:55:";
|
||||
|
||||
COMPARE_ID (nothex, TRUE, nothex, strlen (nothex));
|
||||
COMPARE_ID (allhex, FALSE, allhex_bin, sizeof (allhex_bin));
|
||||
COMPARE_ID (somehex, TRUE, somehex, strlen (somehex));
|
||||
COMPARE_ID (nocolons, TRUE, nocolons, strlen (nocolons));
|
||||
COMPARE_ID (endcolon, TRUE, endcolon, strlen (endcolon));
|
||||
}
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
|
@ -678,6 +714,7 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/dhcp/ip4-missing-prefix-16", test_ip4_missing_prefix_16);
|
||||
g_test_add_func ("/dhcp/ip4-missing-prefix-8", test_ip4_missing_prefix_8);
|
||||
g_test_add_func ("/dhcp/ip4-prefix-classless", test_ip4_prefix_classless);
|
||||
g_test_add_func ("/dhcp/client-id-from-string", test_client_id_from_string);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue