1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include "sd-dhcp6-client.h"
5 
6 #include "hash-funcs.h"
7 #include "list.h"
8 #include "macro.h"
9 #include "ordered-set.h"
10 #include "sparse-endian.h"
11 
12 typedef struct sd_dhcp6_option {
13         unsigned n_ref;
14 
15         uint32_t enterprise_identifier;
16         uint16_t option;
17         void *data;
18         size_t length;
19 } sd_dhcp6_option;
20 
21 extern const struct hash_ops dhcp6_option_hash_ops;
22 
23 /* Common option header */
24 typedef struct DHCP6Option {
25         be16_t code;
26         be16_t len;
27         uint8_t data[];
28 } _packed_ DHCP6Option;
29 
30 /* Address option */
31 struct iaaddr {
32         struct in6_addr address;
33         be32_t lifetime_preferred;
34         be32_t lifetime_valid;
35 } _packed_;
36 
37 /* Prefix Delegation Prefix option */
38 struct iapdprefix {
39         be32_t lifetime_preferred;
40         be32_t lifetime_valid;
41         uint8_t prefixlen;
42         struct in6_addr address;
43 } _packed_;
44 
45 typedef struct DHCP6Address DHCP6Address;
46 
47 struct DHCP6Address {
48         LIST_FIELDS(DHCP6Address, addresses);
49 
50         union {
51                 struct iaaddr iaaddr;
52                 struct iapdprefix iapdprefix;
53         };
54 };
55 
56 struct ia_header {
57         be32_t id;
58         be32_t lifetime_t1;
59         be32_t lifetime_t2;
60 } _packed_;
61 
62 typedef struct DHCP6IA {
63         uint16_t type;
64         struct ia_header header;
65 
66         LIST_HEAD(DHCP6Address, addresses);
67 } DHCP6IA;
68 
69 void dhcp6_ia_clear_addresses(DHCP6IA *ia);
70 DHCP6IA *dhcp6_ia_free(DHCP6IA *ia);
71 DEFINE_TRIVIAL_CLEANUP_FUNC(DHCP6IA*, dhcp6_ia_free);
72 
73 bool dhcp6_option_can_request(uint16_t option);
74 
75 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
76                         size_t optlen, const void *optval);
77 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
78 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
79 int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
80 int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
81 int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedSet *vendor_options);
82 
83 int dhcp6_option_parse(
84                 const uint8_t *buf,
85                 size_t buflen,
86                 size_t *offset,
87                 uint16_t *ret_option_code,
88                 size_t *ret_option_data_len,
89                 const uint8_t **ret_option_data);
90 int dhcp6_option_parse_status(const uint8_t *data, size_t data_len, char **ret_status_message);
91 int dhcp6_option_parse_ia(
92                 sd_dhcp6_client *client,
93                 be32_t iaid,
94                 uint16_t option_code,
95                 size_t option_data_len,
96                 const uint8_t *option_data,
97                 DHCP6IA **ret);
98 int dhcp6_option_parse_addresses(
99                 const uint8_t *optval,
100                 size_t optlen,
101                 struct in6_addr **addrs,
102                 size_t *count);
103 int dhcp6_option_parse_domainname_list(const uint8_t *optval, size_t optlen, char ***ret);
104 int dhcp6_option_parse_domainname(const uint8_t *optval, size_t optlen, char **ret);
105