]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-message: introduce dhcp_message_{append,get}_option_sec()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 13 Apr 2026 02:23:03 +0000 (11:23 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 12 May 2026 15:27:49 +0000 (00:27 +0900)
These are for e.g. DHCP options 51 (lease time), 58 (renewal time), and
59 (rebinding time).

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

index eb43c7e6e534f78b97a0fc6a1b7eb0751c7e43d5..85976ec6ed1d03283dbc972113ce2db34307a230 100644 (file)
@@ -9,6 +9,7 @@
 #include "iovec-util.h"
 #include "iovec-wrapper.h"
 #include "ip-util.h"
+#include "network-common.h"
 
 static sd_dhcp_message* dhcp_message_free(sd_dhcp_message *message) {
         if (!message)
@@ -161,6 +162,11 @@ int dhcp_message_append_option_be32(sd_dhcp_message *message, uint8_t code, be32
         return dhcp_message_append_option(message, code, sizeof(be32_t), &data);
 }
 
+int dhcp_message_append_option_sec(sd_dhcp_message *message, uint8_t code, usec_t usec) {
+        assert(message);
+        return dhcp_message_append_option_be32(message, code, usec_to_be32_sec(usec));
+}
+
 int dhcp_message_get_option(sd_dhcp_message *message, uint8_t code, size_t length, void *ret) {
         int r;
 
@@ -211,6 +217,21 @@ int dhcp_message_get_option_be32(sd_dhcp_message *message, uint8_t code, be32_t
         return dhcp_message_get_option(message, code, sizeof(be32_t), ret);
 }
 
+int dhcp_message_get_option_sec(sd_dhcp_message *message, uint8_t code, bool max_as_infinity, usec_t *ret) {
+        int r;
+
+        assert(message);
+
+        be32_t t;
+        r = dhcp_message_get_option_be32(message, code, &t);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = be32_sec_to_usec(t, max_as_infinity);
+        return 0;
+}
+
 static int dhcp_message_verify_header(
                 const struct iovec *iov,
                 uint8_t op,
index a4ff1c8a656a3fe9f9c77c4647fe33e97a212f02..6086cda3c58f164f11e48c37edc1cad23c7f9446 100644 (file)
@@ -34,6 +34,7 @@ int dhcp_message_append_option_flag(sd_dhcp_message *message, uint8_t code);
 int dhcp_message_append_option_u8(sd_dhcp_message *message, uint8_t code, uint8_t data);
 int dhcp_message_append_option_u16(sd_dhcp_message *message, uint8_t code, uint16_t data);
 int dhcp_message_append_option_be32(sd_dhcp_message *message, uint8_t code, be32_t data);
+int dhcp_message_append_option_sec(sd_dhcp_message *message, uint8_t code, usec_t usec);
 
 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);
@@ -41,6 +42,7 @@ int dhcp_message_get_option_flag(sd_dhcp_message *message, uint8_t code);
 int dhcp_message_get_option_u8(sd_dhcp_message *message, uint8_t code, uint8_t *ret);
 int dhcp_message_get_option_u16(sd_dhcp_message *message, uint8_t code, uint16_t *ret);
 int dhcp_message_get_option_be32(sd_dhcp_message *message, uint8_t code, be32_t *ret);
+int dhcp_message_get_option_sec(sd_dhcp_message *message, uint8_t code, bool max_as_infinity, usec_t *ret);
 
 int dhcp_message_parse(
                 const struct iovec *iov,
index 407fc0f16a1bbbf9c809029249dc807bec14749b..3ac8a66d21ea3fe5c9f7dfe2728c5cfbe215ce58 100644 (file)
@@ -42,6 +42,18 @@ static void verify_u16(sd_dhcp_message *m, uint16_t expected) {
         ASSERT_EQ(u, expected);
 }
 
+static void verify_sec(sd_dhcp_message *m, usec_t expected) {
+        usec_t t;
+        ASSERT_OK(dhcp_message_get_option_sec(m, SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, /* max_as_infinity= */ false, &t));
+        ASSERT_EQ(t, expected);
+        ASSERT_OK(dhcp_message_get_option_sec(m, SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, /* max_as_infinity= */ true, &t));
+        ASSERT_EQ(t, expected);
+        ASSERT_OK(dhcp_message_get_option_sec(m, SD_DHCP_OPTION_RENEWAL_TIME, /* max_as_infinity= */ false, &t));
+        ASSERT_EQ(t, UINT32_MAX * USEC_PER_SEC);
+        ASSERT_OK(dhcp_message_get_option_sec(m, SD_DHCP_OPTION_RENEWAL_TIME, /* max_as_infinity= */ true, &t));
+        ASSERT_EQ(t, USEC_INFINITY);
+}
+
 static void verify_address(sd_dhcp_message *m, const struct in_addr *expected) {
         struct in_addr a;
         ASSERT_OK(dhcp_message_get_option_be32(m, SD_DHCP_OPTION_REQUESTED_IP_ADDRESS, &a.s_addr));
@@ -61,6 +73,8 @@ TEST(dhcp_message) {
                 .ether = {{ 'A', 'B', 'C', '1', '2', '3' }},
         };
 
+        usec_t lease_time = USEC_PER_DAY;
+
         /* 192.0.2.42 */
         struct in_addr addr = { .s_addr = htobe32(0xC000022a) };
 
@@ -95,6 +109,11 @@ TEST(dhcp_message) {
         ASSERT_ERROR(dhcp_message_append_option_u8(m, SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE, 32), EEXIST);
         verify_u16(m, 512);
 
+        /* sec */
+        ASSERT_OK(dhcp_message_append_option_sec(m, SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, lease_time));
+        ASSERT_OK(dhcp_message_append_option_sec(m, SD_DHCP_OPTION_RENEWAL_TIME, USEC_INFINITY));
+        verify_sec(m, lease_time);
+
         /* address */
         ASSERT_OK(dhcp_message_append_option_be32(m, SD_DHCP_OPTION_REQUESTED_IP_ADDRESS, addr.s_addr));
         ASSERT_ERROR(dhcp_message_append_option_be32(m, SD_DHCP_OPTION_REQUESTED_IP_ADDRESS, addr.s_addr), EEXIST);
@@ -123,6 +142,7 @@ TEST(dhcp_message) {
         verify_flag(m2);
         verify_u8(m2, DHCP_DISCOVER);
         verify_u16(m2, 512);
+        verify_sec(m2, lease_time);
         verify_address(m2, &addr);
 
         /* build again, and verify the packet */