#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)
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;
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,
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);
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,
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));
.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) };
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);
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 */