]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-message: introduce dhcp_message_{append,get}_option_client_id()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 19 Apr 2026 06:51:39 +0000 (15:51 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 12 May 2026 15:27:49 +0000 (00:27 +0900)
These are for DHCP option 61 (client ID).

src/libsystemd-network/dhcp-message.c
src/libsystemd-network/dhcp-message.h
src/libsystemd-network/test-dhcp-message.c

index eafc84c179e1342f5a3b95341df7d3b431083415..0882422d11528160ce992ad85e5e8534136031a7 100644 (file)
@@ -3,6 +3,7 @@
 #include <net/if_arp.h>
 
 #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,
index d47d7ba4094ba49214a3ae430f6147e8f063eee7..50c1810c7d672822c7edcbeb0e7d878f27481467 100644 (file)
@@ -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,
index 31e0754d9316dc2c683ad1a55f16848ae2948110..cca5c0603b7bd425f43a4cd9474104a8fff26157 100644 (file)
@@ -3,6 +3,7 @@
 #include <net/if_arp.h>
 
 #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 = {};