mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 10:13:34 +08:00
Merge pull request #30879 from yuwata/dhcp-client-id-json
dhcp: introduce json_dispatch_client_id() and friends
This commit is contained in:
commit
e992753e58
@ -4,6 +4,7 @@
|
||||
#include "sd-dhcp-client-id.h"
|
||||
|
||||
#include "dhcp-duid-internal.h"
|
||||
#include "json.h"
|
||||
#include "macro.h"
|
||||
#include "siphash24.h"
|
||||
#include "sparse-endian.h"
|
||||
@ -55,3 +56,5 @@ static inline bool client_id_data_size_is_valid(size_t size) {
|
||||
|
||||
void client_id_hash_func(const sd_dhcp_client_id *client_id, struct siphash *state);
|
||||
int client_id_compare_func(const sd_dhcp_client_id *a, const sd_dhcp_client_id *b);
|
||||
|
||||
int json_dispatch_client_id(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dhcp-client-id-internal.h"
|
||||
#include "iovec-util.h"
|
||||
#include "unaligned.h"
|
||||
#include "utf8.h"
|
||||
|
||||
@ -51,7 +52,9 @@ int sd_dhcp_client_id_set(
|
||||
|
||||
assert_return(client_id, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(client_id_data_size_is_valid(data_size), -EINVAL);
|
||||
|
||||
if (!client_id_data_size_is_valid(data_size))
|
||||
return -EINVAL;
|
||||
|
||||
client_id->id.type = type;
|
||||
memcpy(client_id->id.data, data, data_size);
|
||||
@ -67,10 +70,12 @@ int sd_dhcp_client_id_set_raw(
|
||||
|
||||
assert_return(client_id, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(client_id_size_is_valid(data_size), -EINVAL);
|
||||
|
||||
/* Unlike sd_dhcp_client_id_set(), this takes whole client ID including its type. */
|
||||
|
||||
if (!client_id_size_is_valid(data_size))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(client_id->raw, data, data_size);
|
||||
|
||||
client_id->size = data_size;
|
||||
@ -150,7 +155,6 @@ int sd_dhcp_client_id_to_string_from_raw(const void *data, size_t data_size, cha
|
||||
int r;
|
||||
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(client_id_size_is_valid(data_size), -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = sd_dhcp_client_id_set_raw(&client_id, data, data_size);
|
||||
@ -174,3 +178,19 @@ int client_id_compare_func(const sd_dhcp_client_id *a, const sd_dhcp_client_id *
|
||||
|
||||
return memcmp_nn(a->raw, a->size, b->raw, b->size);
|
||||
}
|
||||
|
||||
int json_dispatch_client_id(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||
sd_dhcp_client_id *client_id = ASSERT_PTR(userdata);
|
||||
_cleanup_(iovec_done) struct iovec iov = {};
|
||||
int r;
|
||||
|
||||
r = json_dispatch_byte_array_iovec(name, variant, flags, &iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_dhcp_client_id_set_raw(client_id, iov.iov_base, iov.iov_len);
|
||||
if (r < 0)
|
||||
return json_log(variant, flags, r, "Failed to set DHCP client ID from JSON field '%s': %m", strna(name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -71,7 +71,9 @@ int sd_dhcp_duid_set(
|
||||
|
||||
assert_return(duid, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(duid_data_size_is_valid(data_size), -EINVAL);
|
||||
|
||||
if (!duid_data_size_is_valid(data_size))
|
||||
return -EINVAL;
|
||||
|
||||
unaligned_write_be16(&duid->duid.type, duid_type);
|
||||
memcpy(duid->duid.data, data, data_size);
|
||||
@ -87,10 +89,12 @@ int sd_dhcp_duid_set_raw(
|
||||
|
||||
assert_return(duid, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(duid_size_is_valid(data_size), -EINVAL);
|
||||
|
||||
/* Unlike sd_dhcp_duid_set(), this takes whole DUID including its type. */
|
||||
|
||||
if (!duid_size_is_valid(data_size))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(duid->raw, data, data_size);
|
||||
|
||||
duid->size = data_size;
|
||||
@ -209,9 +213,11 @@ int dhcp_duid_to_string_internal(uint16_t type, const void *data, size_t data_si
|
||||
const char *t;
|
||||
|
||||
assert(data);
|
||||
assert(duid_data_size_is_valid(data_size));
|
||||
assert(ret);
|
||||
|
||||
if (!duid_data_size_is_valid(data_size))
|
||||
return -EINVAL;
|
||||
|
||||
x = hexmem(data, data_size);
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "float.h"
|
||||
#include "glyph-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "iovec-util.h"
|
||||
#include "json-internal.h"
|
||||
#include "json.h"
|
||||
#include "macro.h"
|
||||
@ -4993,6 +4995,60 @@ int json_dispatch_unbase64_iovec(const char *name, JsonVariant *variant, JsonDis
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_dispatch_byte_array_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||
_cleanup_free_ uint8_t *buffer = NULL;
|
||||
struct iovec *iov = ASSERT_PTR(userdata);
|
||||
size_t sz, k = 0;
|
||||
|
||||
assert(variant);
|
||||
|
||||
if (!json_variant_is_array(variant))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name));
|
||||
|
||||
sz = json_variant_elements(variant);
|
||||
|
||||
buffer = new(uint8_t, sz);
|
||||
if (!buffer)
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(ENOMEM), "Out of memory.");
|
||||
|
||||
JsonVariant *i;
|
||||
JSON_VARIANT_ARRAY_FOREACH(i, variant) {
|
||||
uint64_t b;
|
||||
|
||||
if (!json_variant_is_unsigned(i))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Element %zu of JSON field '%s' is not an unsigned integer.", k, strna(name));
|
||||
|
||||
b = json_variant_unsigned(i);
|
||||
if (b > 0xff)
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Element %zu of JSON field '%s' is out of range 0%s255.",
|
||||
k, strna(name), special_glyph(SPECIAL_GLYPH_ELLIPSIS));
|
||||
|
||||
buffer[k++] = (uint8_t) b;
|
||||
}
|
||||
assert(k == sz);
|
||||
|
||||
free_and_replace(iov->iov_base, buffer);
|
||||
iov->iov_len = sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_dispatch_in_addr(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||
struct in_addr *address = ASSERT_PTR(userdata);
|
||||
_cleanup_(iovec_done) struct iovec iov = {};
|
||||
int r;
|
||||
|
||||
r = json_dispatch_byte_array_iovec(name, variant, flags, &iov);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (iov.iov_len != sizeof(struct in_addr))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is array of unexpected size.", strna(name));
|
||||
|
||||
memcpy(address, iov.iov_base, iov.iov_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int json_cmp_strings(const void *x, const void *y) {
|
||||
JsonVariant *const *a = x, *const *b = y;
|
||||
|
||||
|
@ -425,6 +425,8 @@ int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDi
|
||||
int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
int json_dispatch_unbase64_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
int json_dispatch_byte_array_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
int json_dispatch_in_addr(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||
|
||||
assert_cc(sizeof(uint32_t) == sizeof(unsigned));
|
||||
#define json_dispatch_uint json_dispatch_uint32
|
||||
|
Loading…
Reference in New Issue
Block a user