return p;
}
+static void ndisc_raw_done(sd_ndisc_raw *raw) {
+ if (!raw)
+ return;
+
+ free(raw->bytes);
+}
+
static void ndisc_rdnss_done(sd_ndisc_rdnss *rdnss) {
if (!rdnss)
return;
return NULL;
switch (option->type) {
+ case 0:
+ ndisc_raw_done(&option->raw);
+ break;
+
case SD_NDISC_OPTION_RDNSS:
ndisc_rdnss_done(&option->rdnss);
break;
return r;
switch (x->type) {
+ case 0:
+ return memcmp_nn(x->raw.bytes, x->raw.length, y->raw.bytes, y->raw.length);
+
case SD_NDISC_OPTION_SOURCE_LL_ADDRESS:
case SD_NDISC_OPTION_TARGET_LL_ADDRESS:
case SD_NDISC_OPTION_REDIRECTED_HEADER:
siphash24_compress_typesafe(option->type, state);
switch (option->type) {
+ case 0:
+ siphash24_compress(option->raw.bytes, option->raw.length, state);
+ break;
+
case SD_NDISC_OPTION_SOURCE_LL_ADDRESS:
case SD_NDISC_OPTION_TARGET_LL_ADDRESS:
case SD_NDISC_OPTION_REDIRECTED_HEADER:
return set_ensure_consume(options, &ndisc_option_hash_ops, p);
}
+int ndisc_option_add_raw(Set **options, size_t offset, size_t length, const uint8_t *bytes) {
+ _cleanup_free_ uint8_t *copy = NULL;
+
+ assert(options);
+ assert(bytes);
+
+ if (length == 0)
+ return -EINVAL;
+
+ copy = newdup(uint8_t, bytes, length);
+ if (!copy)
+ return -ENOMEM;
+
+ sd_ndisc_option *p = ndisc_option_new(/* type = */ 0, offset);
+ if (!p)
+ return -ENOMEM;
+
+ p->raw = (sd_ndisc_raw) {
+ .bytes = TAKE_PTR(copy),
+ .length = length,
+ };
+
+ return ndisc_option_consume(options, p);
+}
+
int ndisc_option_add_link_layer_address(Set **options, uint8_t opt, size_t offset, const struct ether_addr *mac) {
assert(options);
assert(IN_SET(opt, SD_NDISC_OPTION_SOURCE_LL_ADDRESS, SD_NDISC_OPTION_TARGET_LL_ADDRESS));
return log_debug_errno(r, "Failed to parse NDisc option header: %m");
switch (type) {
+ case 0:
+ r = -EBADMSG;
+ break;
+
case SD_NDISC_OPTION_SOURCE_LL_ADDRESS:
case SD_NDISC_OPTION_TARGET_LL_ADDRESS:
r = ndisc_option_parse_link_layer_address(&options, offset, length, opt);
#include "set.h"
#include "time-util.h"
+typedef struct sd_ndisc_raw {
+ uint8_t *bytes;
+ size_t length;
+} sd_ndisc_raw;
+
/* Mostly equivalent to struct nd_opt_prefix_info, but using usec_t. */
typedef struct sd_ndisc_prefix {
uint8_t flags;
size_t offset;
union {
+ sd_ndisc_raw raw; /* for testing or unsupported options */
struct ether_addr mac; /* SD_NDISC_OPTION_SOURCE_LL_ADDRESS or SD_NDISC_OPTION_TARGET_LL_ADDRESS */
sd_ndisc_prefix prefix; /* SD_NDISC_OPTION_PREFIX_INFORMATION */
struct ip6_hdr hdr; /* SD_NDISC_OPTION_REDIRECTED_HEADER */
int ndisc_option_get_mac(Set *options, uint8_t type, struct ether_addr *ret);
+int ndisc_option_add_raw(
+ Set **options,
+ size_t offset,
+ size_t length,
+ const uint8_t *bytes);
int ndisc_option_add_link_layer_address(
Set **options,
uint8_t opt,