summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/ndisc-option.h
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-02-29 04:31:58 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-03-13 04:32:37 +0100
commita163404cc88914142ef8bbfaab0eb39d1a990c02 (patch)
tree0cd6aa4ecbc68b71727db553fba3fc84acc68e74 /src/libsystemd-network/ndisc-option.h
parentsd-ndisc: rename ndisc-protocol.[ch] -> ndisc-option.[ch] (diff)
downloadsystemd-a163404cc88914142ef8bbfaab0eb39d1a990c02.tar.xz
systemd-a163404cc88914142ef8bbfaab0eb39d1a990c02.zip
ndisc-option: introduce generic NDisc option parser
It is not used in this commit, but will be used for parsing NDisc options in Router Advertisement message and friends. The parser does mostly equivalent to what currently we do in sd-ndisc-router.c. Several notable differences are: - also perse source and target link-layer address, - refuse multiple captive portals, - check if the captive portal is in safe characters, as previously we checked that in networkd-ndisc.c, - dedup prefixes, routes, and pref64, - limit the total number of options, for safety.
Diffstat (limited to 'src/libsystemd-network/ndisc-option.h')
-rw-r--r--src/libsystemd-network/ndisc-option.h124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/libsystemd-network/ndisc-option.h b/src/libsystemd-network/ndisc-option.h
index dcb1b191c7..6e6a1ced63 100644
--- a/src/libsystemd-network/ndisc-option.h
+++ b/src/libsystemd-network/ndisc-option.h
@@ -1,9 +1,69 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <inttypes.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+#include "sd-ndisc-protocol.h"
+
#include "icmp6-packet.h"
+#include "macro.h"
+#include "set.h"
#include "time-util.h"
+/* Mostly equivalent to struct nd_opt_prefix_info, but using usec_t. */
+typedef struct sd_ndisc_prefix {
+ uint8_t flags;
+ uint8_t prefixlen;
+ struct in6_addr address;
+ usec_t valid_lifetime;
+ usec_t preferred_lifetime;
+} sd_ndisc_prefix;
+
+typedef struct sd_ndisc_route {
+ uint8_t preference;
+ uint8_t prefixlen;
+ struct in6_addr address;
+ usec_t lifetime;
+} sd_ndisc_route;
+
+typedef struct sd_ndisc_rdnss {
+ size_t n_addresses;
+ struct in6_addr *addresses;
+ usec_t lifetime;
+} sd_ndisc_rdnss;
+
+typedef struct sd_ndisc_dnssl {
+ char **domains;
+ usec_t lifetime;
+} sd_ndisc_dnssl;
+
+typedef struct sd_ndisc_prefix64 {
+ uint8_t prefixlen;
+ struct in6_addr prefix;
+ usec_t lifetime;
+} sd_ndisc_prefix64;
+
+typedef struct sd_ndisc_option {
+ uint8_t type;
+ size_t offset;
+
+ union {
+ 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 */
+ uint32_t mtu; /* SD_NDISC_OPTION_MTU */
+ sd_ndisc_route route; /* SD_NDISC_OPTION_ROUTE_INFORMATION */
+ sd_ndisc_rdnss rdnss; /* SD_NDISC_OPTION_RDNSS */
+ uint64_t extended_flags; /* SD_NDISC_OPTION_FLAGS_EXTENSION */
+ sd_ndisc_dnssl dnssl; /* SD_NDISC_OPTION_DNSSL */
+ char *captive_portal; /* SD_NDISC_OPTION_CAPTIVE_PORTAL */
+ sd_ndisc_prefix64 prefix64; /* SD_NDISC_OPTION_PREF64 */
+ };
+} sd_ndisc_option;
+
/* RFC 8781: PREF64 or (NAT64 prefix) */
#define PREF64_SCALED_LIFETIME_MASK 0xfff8
#define PREF64_PLC_MASK 0x0007
@@ -31,9 +91,73 @@ struct nd_opt_prefix64_info {
int pref64_plc_to_prefix_length(uint16_t plc, uint8_t *ret);
int pref64_prefix_length_to_plc(uint8_t prefixlen, uint8_t *ret);
+sd_ndisc_option* ndisc_option_free(sd_ndisc_option *option);
+
int ndisc_option_parse(
ICMP6Packet *p,
size_t offset,
uint8_t *ret_type,
size_t *ret_len,
const uint8_t **ret_opt);
+
+int ndisc_parse_options(ICMP6Packet *p, Set **ret_options);
+
+static inline sd_ndisc_option* ndisc_option_get(Set *options, uint8_t type) {
+ return set_get(options, &(sd_ndisc_option) { .type = type, });
+}
+
+int ndisc_option_get_mac(Set *options, uint8_t type, struct ether_addr *ret);
+
+int ndisc_option_add_link_layer_address(
+ Set **options,
+ uint8_t opt,
+ size_t offset,
+ const struct ether_addr *mac);
+int ndisc_option_add_prefix(
+ Set **options,
+ size_t offset,
+ uint8_t flags,
+ uint8_t prefixlen,
+ const struct in6_addr *address,
+ usec_t valid_lifetime,
+ usec_t preferred_lifetime);
+int ndisc_option_add_redirected_header(
+ Set **options,
+ size_t offset,
+ const struct ip6_hdr *hdr);
+int ndisc_option_add_mtu(
+ Set **options,
+ size_t offset,
+ uint32_t mtu);
+int ndisc_option_add_route(
+ Set **options,
+ size_t offset,
+ uint8_t preference,
+ uint8_t prefixlen,
+ const struct in6_addr *prefix,
+ usec_t lifetime);
+int ndisc_option_add_rdnss(
+ Set **options,
+ size_t offset,
+ size_t n_addresses,
+ const struct in6_addr *addresses,
+ usec_t lifetime);
+int ndisc_option_add_flags_extension(
+ Set **options,
+ size_t offset,
+ uint64_t flags);
+int ndisc_option_add_dnssl(
+ Set **options,
+ size_t offset,
+ char * const *domains,
+ usec_t lifetime);
+int ndisc_option_add_captive_portal(
+ Set **options,
+ size_t offset,
+ const char *portal);
+int ndisc_option_add_prefix64(
+ Set **options,
+ size_t offset,
+ uint8_t prefixlen,
+ const struct in6_addr *prefix,
+ usec_t lifetime);