From: Yu Watanabe Date: Mon, 13 Apr 2026 02:23:03 +0000 (+0900) Subject: dhcp-message: introduce dhcp_message_{append,get}_option_sec() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b97d772a25954d9b35e6856aed323ac54fa468b;p=thirdparty%2Fsystemd.git dhcp-message: introduce dhcp_message_{append,get}_option_sec() These are for e.g. DHCP options 51 (lease time), 58 (renewal time), and 59 (rebinding time). --- diff --git a/src/libsystemd-network/dhcp-message.c b/src/libsystemd-network/dhcp-message.c index eb43c7e6e53..85976ec6ed1 100644 --- a/src/libsystemd-network/dhcp-message.c +++ b/src/libsystemd-network/dhcp-message.c @@ -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, diff --git a/src/libsystemd-network/dhcp-message.h b/src/libsystemd-network/dhcp-message.h index a4ff1c8a656..6086cda3c58 100644 --- a/src/libsystemd-network/dhcp-message.h +++ b/src/libsystemd-network/dhcp-message.h @@ -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, diff --git a/src/libsystemd-network/test-dhcp-message.c b/src/libsystemd-network/test-dhcp-message.c index 407fc0f16a1..3ac8a66d21e 100644 --- a/src/libsystemd-network/test-dhcp-message.c +++ b/src/libsystemd-network/test-dhcp-message.c @@ -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 */