]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/dhcp6-internal.h
40578220d32b5dd5ea0a76c63ea1febee0fe3be3
[thirdparty/systemd.git] / src / libsystemd-network / dhcp6-internal.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 /***
5 Copyright © 2014-2015 Intel Corporation. All rights reserved.
6 ***/
7
8 #include <net/ethernet.h>
9 #include <netinet/in.h>
10
11 #include "sd-event.h"
12 #include "sd-dhcp6-client.h"
13
14 #include "dhcp-identifier.h"
15 #include "dhcp6-protocol.h"
16 #include "ether-addr-util.h"
17 #include "hashmap.h"
18 #include "list.h"
19 #include "macro.h"
20 #include "network-common.h"
21 #include "sparse-endian.h"
22
23 typedef struct sd_dhcp6_option {
24 unsigned n_ref;
25
26 uint32_t enterprise_identifier;
27 uint16_t option;
28 void *data;
29 size_t length;
30 } sd_dhcp6_option;
31
32 extern const struct hash_ops dhcp6_option_hash_ops;
33
34 /* Common option header */
35 typedef struct DHCP6Option {
36 be16_t code;
37 be16_t len;
38 uint8_t data[];
39 } _packed_ DHCP6Option;
40
41 /* Address option */
42 struct iaaddr {
43 struct in6_addr address;
44 be32_t lifetime_preferred;
45 be32_t lifetime_valid;
46 } _packed_;
47
48 /* Prefix Delegation Prefix option */
49 struct iapdprefix {
50 be32_t lifetime_preferred;
51 be32_t lifetime_valid;
52 uint8_t prefixlen;
53 struct in6_addr address;
54 } _packed_;
55
56 typedef struct DHCP6Address DHCP6Address;
57
58 struct DHCP6Address {
59 LIST_FIELDS(DHCP6Address, addresses);
60
61 union {
62 struct iaaddr iaaddr;
63 struct iapdprefix iapdprefix;
64 };
65 };
66
67 struct ia_header {
68 be32_t id;
69 be32_t lifetime_t1;
70 be32_t lifetime_t2;
71 } _packed_;
72
73 typedef struct DHCP6IA {
74 uint16_t type;
75 struct ia_header header;
76
77 LIST_HEAD(DHCP6Address, addresses);
78 } DHCP6IA;
79
80 /* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
81 typedef enum DHCP6RequestIA {
82 DHCP6_REQUEST_IA_NA = 1 << 0,
83 DHCP6_REQUEST_IA_TA = 1 << 1, /* currently not used */
84 DHCP6_REQUEST_IA_PD = 1 << 2,
85 } DHCP6RequestIA;
86
87 typedef struct sd_dhcp6_client {
88 unsigned n_ref;
89
90 DHCP6State state;
91 sd_event *event;
92 int event_priority;
93 int ifindex;
94 char *ifname;
95 struct in6_addr local_address;
96 struct hw_addr_data hw_addr;
97 uint16_t arp_type;
98 DHCP6IA ia_na;
99 DHCP6IA ia_pd;
100 DHCP6RequestIA request_ia;
101 be32_t transaction_id;
102 usec_t transaction_start;
103 struct sd_dhcp6_lease *lease;
104 int fd;
105 bool information_request;
106 bool iaid_set;
107 be16_t *req_opts;
108 size_t req_opts_len;
109 char *fqdn;
110 char *mudurl;
111 char **user_class;
112 char **vendor_class;
113 sd_event_source *receive_message;
114 usec_t retransmit_time;
115 uint8_t retransmit_count;
116 sd_event_source *timeout_resend;
117 sd_event_source *timeout_expire;
118 sd_event_source *timeout_t1;
119 sd_event_source *timeout_t2;
120 sd_dhcp6_client_callback_t callback;
121 void *userdata;
122 struct duid duid;
123 size_t duid_len;
124 usec_t information_request_time_usec;
125 usec_t information_refresh_time_usec;
126 OrderedHashmap *extra_options;
127 OrderedHashmap *vendor_options;
128
129 /* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
130 bool test_mode;
131 } sd_dhcp6_client;
132
133 bool dhcp6_option_can_request(uint16_t option);
134 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
135 size_t optlen, const void *optval);
136 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
137 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
138 int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
139 int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
140 int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
141
142 int dhcp6_option_parse(
143 const uint8_t *buf,
144 size_t buflen,
145 size_t *offset,
146 uint16_t *ret_option_code,
147 size_t *ret_option_data_len,
148 const uint8_t **ret_option_data);
149 int dhcp6_option_parse_status(const uint8_t *data, size_t data_len, char **ret_status_message);
150 int dhcp6_option_parse_ia(
151 sd_dhcp6_client *client,
152 be32_t iaid,
153 uint16_t option_code,
154 size_t option_data_len,
155 const uint8_t *option_data,
156 DHCP6IA **ret);
157 int dhcp6_option_parse_addresses(
158 const uint8_t *optval,
159 size_t optlen,
160 struct in6_addr **addrs,
161 size_t *count);
162 int dhcp6_option_parse_domainname_list(const uint8_t *optval, size_t optlen, char ***ret);
163 int dhcp6_option_parse_domainname(const uint8_t *optval, size_t optlen, char **ret);
164
165 int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
166 int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
167 const void *packet, size_t len);
168
169 const char *dhcp6_message_type_to_string(DHCP6MessageType t) _const_;
170 DHCP6MessageType dhcp6_message_type_from_string(const char *s) _pure_;
171 const char *dhcp6_message_status_to_string(DHCP6Status s) _const_;
172 DHCP6Status dhcp6_message_status_from_string(const char *s) _pure_;
173
174 void dhcp6_client_set_test_mode(sd_dhcp6_client *client, bool test_mode);
175
176 #define log_dhcp6_client_errno(client, error, fmt, ...) \
177 log_interface_prefix_full_errno( \
178 "DHCPv6 client: ", \
179 sd_dhcp6_client, client, \
180 error, fmt, ##__VA_ARGS__)
181 #define log_dhcp6_client(client, fmt, ...) \
182 log_interface_prefix_full_errno_zerook( \
183 "DHCPv6 client: ", \
184 sd_dhcp6_client, client, \
185 0, fmt, ##__VA_ARGS__)