From: Yu Watanabe Date: Sun, 19 Apr 2026 06:51:39 +0000 (+0900) Subject: dhcp-message: introduce dhcp_message_{append,get}_option_client_id() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a6a6e371f76f5fac2abd6255be076941a2841403;p=thirdparty%2Fsystemd.git dhcp-message: introduce dhcp_message_{append,get}_option_client_id() These are for DHCP option 61 (client ID). --- diff --git a/src/libsystemd-network/dhcp-message.c b/src/libsystemd-network/dhcp-message.c index eafc84c179e..0882422d115 100644 --- a/src/libsystemd-network/dhcp-message.c +++ b/src/libsystemd-network/dhcp-message.c @@ -3,6 +3,7 @@ #include #include "alloc-util.h" +#include "dhcp-client-id-internal.h" #include "dhcp-message.h" #include "dhcp-protocol.h" #include "ether-addr-util.h" @@ -202,6 +203,19 @@ int dhcp_message_append_option_string(sd_dhcp_message *message, uint8_t code, co return dhcp_message_append_option(message, code, strlen(data), data); } +int dhcp_message_append_option_client_id(sd_dhcp_message *message, const sd_dhcp_client_id *id) { + assert(message); + assert(id); + + if (!sd_dhcp_client_id_is_set(id)) + return -EINVAL; + + if (dhcp_message_has_option(message, SD_DHCP_OPTION_CLIENT_IDENTIFIER)) + return -EEXIST; + + return dhcp_message_append_option(message, SD_DHCP_OPTION_CLIENT_IDENTIFIER, id->size, id->raw); +} + int dhcp_message_get_option(sd_dhcp_message *message, uint8_t code, size_t length, void *ret) { int r; @@ -329,6 +343,20 @@ int dhcp_message_get_option_string(sd_dhcp_message *message, uint8_t code, char return 0; } +int dhcp_message_get_option_client_id(sd_dhcp_message *message, sd_dhcp_client_id *ret) { + int r; + + assert(message); + assert(ret); + + _cleanup_(iovec_done) struct iovec iov = {}; + r = dhcp_message_get_option_alloc(message, SD_DHCP_OPTION_CLIENT_IDENTIFIER, &iov); + if (r < 0) + return r; + + return sd_dhcp_client_id_set_raw(ret, iov.iov_base, iov.iov_len); +} + static int dhcp_message_verify_header( const struct iovec *iov, uint8_t op, diff --git a/src/libsystemd-network/dhcp-message.h b/src/libsystemd-network/dhcp-message.h index d47d7ba4094..50c1810c7d6 100644 --- a/src/libsystemd-network/dhcp-message.h +++ b/src/libsystemd-network/dhcp-message.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "sd-dhcp-client-id.h" #include "sd-forward.h" #include "sparse-endian.h" @@ -38,6 +39,7 @@ int dhcp_message_append_option_sec(sd_dhcp_message *message, uint8_t code, usec_ int dhcp_message_append_option_address(sd_dhcp_message *message, uint8_t code, const struct in_addr *addr); int dhcp_message_append_option_addresses(sd_dhcp_message *message, uint8_t code, size_t n_addr, const struct in_addr *addr); int dhcp_message_append_option_string(sd_dhcp_message *message, uint8_t code, const char *data); +int dhcp_message_append_option_client_id(sd_dhcp_message *message, const sd_dhcp_client_id *id); int dhcp_message_get_option(sd_dhcp_message *message, uint8_t code, size_t length, void *ret); int dhcp_message_get_option_alloc(sd_dhcp_message *message, uint8_t code, struct iovec *ret); @@ -49,6 +51,7 @@ int dhcp_message_get_option_sec(sd_dhcp_message *message, uint8_t code, bool max int dhcp_message_get_option_address(sd_dhcp_message *message, uint8_t code, struct in_addr *ret); int dhcp_message_get_option_addresses(sd_dhcp_message *message, uint8_t code, size_t *ret_n_addr, struct in_addr **ret_addr); int dhcp_message_get_option_string(sd_dhcp_message *message, uint8_t code, char **ret); +int dhcp_message_get_option_client_id(sd_dhcp_message *message, sd_dhcp_client_id *ret); int dhcp_message_parse( const struct iovec *iov, diff --git a/src/libsystemd-network/test-dhcp-message.c b/src/libsystemd-network/test-dhcp-message.c index 31e0754d931..cca5c0603b7 100644 --- a/src/libsystemd-network/test-dhcp-message.c +++ b/src/libsystemd-network/test-dhcp-message.c @@ -3,6 +3,7 @@ #include #include "alloc-util.h" +#include "dhcp-client-id-internal.h" #include "dhcp-message.h" #include "dhcp-protocol.h" #include "ether-addr-util.h" @@ -94,6 +95,12 @@ static void verify_multiple_strings(sd_dhcp_message *m, char * const *expected) ASSERT_STREQ(s, joined); } +static void verify_client_id(sd_dhcp_message *m, const sd_dhcp_client_id *expected) { + sd_dhcp_client_id id = {}; + ASSERT_OK(dhcp_message_get_option_client_id(m, &id)); + ASSERT_EQ(client_id_compare_func(&id, expected), 0); +} + TEST(dhcp_message) { _cleanup_(sd_dhcp_message_unrefp) sd_dhcp_message *m = NULL; @@ -120,6 +127,11 @@ TEST(dhcp_message) { { .s_addr = htobe32(0xC0000204) }, }; + sd_dhcp_client_id id = { + .raw = { 1, 3, 3, 3, 3, 3, 3, }, + .size = 7, + }; + const char *vendor_class = "hogehoge"; char **root_path = STRV_MAKE("/path/to/root", "/hogehoge/foofoo"); @@ -190,6 +202,10 @@ TEST(dhcp_message) { ASSERT_OK(dhcp_message_append_option_string(m, SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER, vendor_class)); verify_string(m, vendor_class); + /* client ID */ + ASSERT_OK(dhcp_message_append_option_client_id(m, &id)); + verify_client_id(m, &id); + /* build and parse */ _cleanup_(iovw_done_free) struct iovec_wrapper iovw = {}; ASSERT_OK(dhcp_message_build(m, &iovw)); @@ -218,6 +234,7 @@ TEST(dhcp_message) { verify_address(m2, &addr); verify_addresses(m2, ELEMENTSOF(ntp), ntp); verify_string(m2, vendor_class); + verify_client_id(m2, &id); /* build again, and verify the packet */ _cleanup_(iovw_done_free) struct iovec_wrapper iovw2 = {};