dhcp-message: introduce dhcp_message_{append,get}_option_parameter_request_list()
These are for DHCP option 55 (parameter request list).
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include "iovec-wrapper.h"
|
||||
#include "ip-util.h"
|
||||
#include "network-common.h"
|
||||
#include "set.h"
|
||||
#include "sort-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static sd_dhcp_message* dhcp_message_free(sd_dhcp_message *message) {
|
||||
@@ -216,6 +218,35 @@ int dhcp_message_append_option_client_id(sd_dhcp_message *message, const sd_dhcp
|
||||
return dhcp_message_append_option(message, SD_DHCP_OPTION_CLIENT_IDENTIFIER, id->size, id->raw);
|
||||
}
|
||||
|
||||
static int cmp_uint8(const uint8_t *a, const uint8_t *b) {
|
||||
assert(a);
|
||||
assert(b);
|
||||
|
||||
return CMP(*a, *b);
|
||||
}
|
||||
|
||||
int dhcp_message_append_option_parameter_request_list(sd_dhcp_message *message, Set *prl) {
|
||||
assert(message);
|
||||
|
||||
size_t len = set_size(prl);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
_cleanup_free_ uint8_t *buf = new(uint8_t, len);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
uint8_t *p = buf;
|
||||
void *q;
|
||||
SET_FOREACH(q, prl)
|
||||
*p++ = PTR_TO_UINT8(q);
|
||||
|
||||
/* Sort the options to make the message reproducible. */
|
||||
typesafe_qsort(buf, len, cmp_uint8);
|
||||
|
||||
return dhcp_message_append_option(message, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST, len, buf);
|
||||
}
|
||||
|
||||
int dhcp_message_get_option(sd_dhcp_message *message, uint8_t code, size_t length, void *ret) {
|
||||
int r;
|
||||
|
||||
@@ -357,6 +388,33 @@ int dhcp_message_get_option_client_id(sd_dhcp_message *message, sd_dhcp_client_i
|
||||
return sd_dhcp_client_id_set_raw(ret, iov.iov_base, iov.iov_len);
|
||||
}
|
||||
|
||||
int dhcp_message_get_option_parameter_request_list(sd_dhcp_message *message, Set **ret) {
|
||||
int r;
|
||||
|
||||
assert(message);
|
||||
|
||||
_cleanup_(iovec_done) struct iovec iov = {};
|
||||
r = dhcp_message_get_option_alloc(message, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST, &iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!iovec_is_set(&iov))
|
||||
return -ENODATA;
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
_cleanup_set_free_ Set *prl = NULL;
|
||||
for (struct iovec i = iov; iovec_is_set(&i); iovec_inc(&i, 1)) {
|
||||
r = set_ensure_put(&prl, /* hash_ops= */ NULL, UINT8_TO_PTR(*(uint8_t*) i.iov_base));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(prl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_message_verify_header(
|
||||
const struct iovec *iov,
|
||||
uint8_t op,
|
||||
|
||||
@@ -40,6 +40,7 @@ int dhcp_message_append_option_address(sd_dhcp_message *message, uint8_t code, c
|
||||
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_append_option_parameter_request_list(sd_dhcp_message *message, Set *prl);
|
||||
|
||||
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);
|
||||
@@ -52,6 +53,7 @@ int dhcp_message_get_option_address(sd_dhcp_message *message, uint8_t code, stru
|
||||
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_get_option_parameter_request_list(sd_dhcp_message *message, Set **ret);
|
||||
|
||||
int dhcp_message_parse(
|
||||
const struct iovec *iov,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "iovec-util.h"
|
||||
#include "iovec-wrapper.h"
|
||||
#include "random-util.h"
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
|
||||
@@ -101,6 +102,12 @@ static void verify_client_id(sd_dhcp_message *m, const sd_dhcp_client_id *expect
|
||||
ASSERT_EQ(client_id_compare_func(&id, expected), 0);
|
||||
}
|
||||
|
||||
static void verify_prl(sd_dhcp_message *m, Set *expected) {
|
||||
_cleanup_set_free_ Set *set = NULL;
|
||||
ASSERT_OK(dhcp_message_get_option_parameter_request_list(m, &set));
|
||||
ASSERT_TRUE(set_equal(set, expected));
|
||||
}
|
||||
|
||||
TEST(dhcp_message) {
|
||||
_cleanup_(sd_dhcp_message_unrefp) sd_dhcp_message *m = NULL;
|
||||
|
||||
@@ -132,6 +139,10 @@ TEST(dhcp_message) {
|
||||
.size = 7,
|
||||
};
|
||||
|
||||
_cleanup_set_free_ Set *prl = NULL;
|
||||
for (uint8_t i = SD_DHCP_OPTION_PRIVATE_BASE; i <= SD_DHCP_OPTION_PRIVATE_LAST; i++)
|
||||
ASSERT_OK(set_ensure_put(&prl, /* hash_ops= */ NULL, UINT_TO_PTR(i)));
|
||||
|
||||
const char *vendor_class = "hogehoge";
|
||||
char **root_path = STRV_MAKE("/path/to/root", "/hogehoge/foofoo");
|
||||
|
||||
@@ -206,6 +217,11 @@ TEST(dhcp_message) {
|
||||
ASSERT_OK(dhcp_message_append_option_client_id(m, &id));
|
||||
verify_client_id(m, &id);
|
||||
|
||||
/* parameter request list */
|
||||
ASSERT_OK(dhcp_message_append_option_parameter_request_list(m, prl));
|
||||
ASSERT_OK(dhcp_message_append_option_parameter_request_list(m, prl));
|
||||
verify_prl(m, prl);
|
||||
|
||||
/* build and parse */
|
||||
_cleanup_(iovw_done_free) struct iovec_wrapper iovw = {};
|
||||
ASSERT_OK(dhcp_message_build(m, &iovw));
|
||||
@@ -235,6 +251,7 @@ TEST(dhcp_message) {
|
||||
verify_addresses(m2, ELEMENTSOF(ntp), ntp);
|
||||
verify_string(m2, vendor_class);
|
||||
verify_client_id(m2, &id);
|
||||
verify_prl(m2, prl);
|
||||
|
||||
/* build again, and verify the packet */
|
||||
_cleanup_(iovw_done_free) struct iovec_wrapper iovw2 = {};
|
||||
|
||||
Reference in New Issue
Block a user