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).
This commit is contained in:
Yu Watanabe
2026-05-13 00:27:49 +09:00
parent 8c18bb6547
commit 7b97d772a2
3 changed files with 43 additions and 0 deletions
+21
View 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,
+2
View 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,
@@ -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 */