]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/test-dhcp6-client.c
tree-wide: introduce PIPE_EBADF macro
[thirdparty/systemd.git] / src / libsystemd-network / test-dhcp6-client.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3 Copyright © 2014 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <net/ethernet.h>
7 #include <net/if_arp.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include "sd-dhcp6-client.h"
14 #include "sd-event.h"
15
16 #include "dhcp-identifier.h"
17 #include "dhcp6-internal.h"
18 #include "dhcp6-lease-internal.h"
19 #include "dhcp6-protocol.h"
20 #include "fd-util.h"
21 #include "macro.h"
22 #include "memory-util.h"
23 #include "socket-util.h"
24 #include "string-util.h"
25 #include "strv.h"
26 #include "tests.h"
27 #include "time-util.h"
28
29 #define DHCP6_CLIENT_EVENT_TEST_ADVERTISED 77
30 #define IA_ID_BYTES \
31 0x0e, 0xcf, 0xa3, 0x7d
32 #define IA_NA_ADDRESS1_BYTES \
33 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c, 0x55, 0xad
34 #define IA_NA_ADDRESS2_BYTES \
35 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c, 0x55, 0xae
36 #define IA_PD_PREFIX1_BYTES \
37 0x2a, 0x02, 0x81, 0x0d, 0x98, 0x80, 0x37, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
38 #define IA_PD_PREFIX2_BYTES \
39 0x2a, 0x02, 0x81, 0x0d, 0x98, 0x80, 0x37, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
40 #define DNS1_BYTES \
41 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
42 #define DNS2_BYTES \
43 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
44 #define SNTP1_BYTES \
45 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
46 #define SNTP2_BYTES \
47 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04
48 #define NTP1_BYTES \
49 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05
50 #define NTP2_BYTES \
51 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
52 #define CLIENT_ID_BYTES \
53 0x00, 0x02, 0x00, 0x00, 0xab, 0x11, 0x61, 0x77, 0x40, 0xde, 0x13, 0x42, 0xc3, 0xa2
54 #define SERVER_ID_BYTES \
55 0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53
56
57 static const struct in6_addr local_address =
58 { { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, } } };
59 static const struct in6_addr mcast_address =
60 IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
61 static const struct in6_addr ia_na_address1 = { { { IA_NA_ADDRESS1_BYTES } } };
62 static const struct in6_addr ia_na_address2 = { { { IA_NA_ADDRESS2_BYTES } } };
63 static const struct in6_addr ia_pd_prefix1 = { { { IA_PD_PREFIX1_BYTES } } };
64 static const struct in6_addr ia_pd_prefix2 = { { { IA_PD_PREFIX2_BYTES } } };
65 static const struct in6_addr dns1 = { { { DNS1_BYTES } } };
66 static const struct in6_addr dns2 = { { { DNS2_BYTES } } };
67 static const struct in6_addr sntp1 = { { { SNTP1_BYTES } } };
68 static const struct in6_addr sntp2 = { { { SNTP2_BYTES } } };
69 static const struct in6_addr ntp1 = { { { NTP1_BYTES } } };
70 static const struct in6_addr ntp2 = { { { NTP2_BYTES } } };
71 static const uint8_t client_id[] = { CLIENT_ID_BYTES };
72 static const uint8_t server_id[] = { SERVER_ID_BYTES };
73 static const struct ether_addr mac = {
74 .ether_addr_octet = { 'A', 'B', 'C', '1', '2', '3' },
75 };
76 static int test_fd[2] = PIPE_EBADF;
77 static int test_ifindex = 42;
78 static unsigned test_client_sent_message_count = 0;
79 static sd_dhcp6_client *client_ref = NULL;
80
81 TEST(client_basic) {
82 _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
83 int v;
84
85 assert_se(sd_dhcp6_client_new(&client) >= 0);
86 assert_se(client);
87
88 assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
89 assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
90
91 assert_se(sd_dhcp6_client_set_mac(client, mac.ether_addr_octet, sizeof(mac), ARPHRD_ETHER) >= 0);
92
93 assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1);
94 assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1);
95 assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1);
96 assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
97 assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
98
99 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL);
100 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
101 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) >= 0);
102 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVER) >= 0);
103 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0);
104 assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
105 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVER) >= 0);
106 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVER) >= 0);
107 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVER) == -EEXIST);
108 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVER) == -EEXIST);
109
110 assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
111 v = 0;
112 assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
113 assert_se(v);
114 assert_se(sd_dhcp6_client_set_information_request(client, 0) >= 0);
115 v = 42;
116 assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
117 assert_se(v == 0);
118
119 v = 0;
120 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
121 assert_se(v);
122 v = 0;
123 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
124 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
125 assert_se(v);
126 v = 42;
127 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
128 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
129 assert_se(v);
130
131 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
132 assert_se(sd_dhcp6_client_set_prefix_delegation(client, 1) >= 0);
133 v = 0;
134 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
135 assert_se(v);
136 v = 0;
137 assert_se(sd_dhcp6_client_get_prefix_delegation(client, &v) >= 0);
138 assert_se(v);
139
140 assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
141
142 assert_se(sd_dhcp6_client_detach_event(client) >= 0);
143 }
144
145 TEST(parse_domain) {
146 _cleanup_free_ char *domain = NULL;
147 _cleanup_strv_free_ char **list = NULL;
148 uint8_t *data;
149
150 data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0 };
151 assert_se(dhcp6_option_parse_domainname(data, 13, &domain) >= 0);
152 assert_se(domain);
153 assert_se(streq(domain, "example.com"));
154 domain = mfree(domain);
155
156 data = (uint8_t []) { 4, 't', 'e', 's', 't' };
157 assert_se(dhcp6_option_parse_domainname(data, 5, &domain) >= 0);
158 assert_se(domain);
159 assert_se(streq(domain, "test"));
160 domain = mfree(domain);
161
162 data = (uint8_t []) { 0 };
163 assert_se(dhcp6_option_parse_domainname(data, 1, &domain) < 0);
164
165 data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0,
166 6, 'f', 'o', 'o', 'b', 'a', 'r', 0 };
167 assert_se(dhcp6_option_parse_domainname_list(data, 21, &list) >= 0);
168 assert_se(list);
169 assert_se(streq(list[0], "example.com"));
170 assert_se(streq(list[1], "foobar"));
171 assert_se(!list[2]);
172 list = strv_free(list);
173
174 data = (uint8_t []) { 1, 'a', 0, 20, 'b', 'c' };
175 assert_se(dhcp6_option_parse_domainname_list(data, 6, &list) < 0);
176
177 data = (uint8_t []) { 0 , 0 };
178 assert_se(dhcp6_option_parse_domainname_list(data, 2, &list) < 0);
179 }
180
181 TEST(option) {
182 static const uint8_t packet[] = {
183 'F', 'O', 'O', 'H', 'O', 'G', 'E',
184 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x07,
185 'A', 'B', 'C', 'D', 'E', 'F', 'G',
186 0x00, SD_DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
187 '1', '2', '3', '4', '5', '6', '7', '8', '9',
188 'B', 'A', 'R',
189 };
190 static const uint8_t result[] = {
191 'F', 'O', 'O', 'H', 'O', 'G', 'E',
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 'B', 'A', 'R',
196 };
197 _cleanup_free_ uint8_t *buf = NULL;
198 size_t offset, pos, optlen;
199 const uint8_t *optval;
200 uint16_t optcode;
201
202 assert_se(sizeof(packet) == sizeof(result));
203
204 offset = 0;
205 assert_se(dhcp6_option_parse(packet, 0, &offset, &optcode, &optlen, &optval) == -EBADMSG);
206
207 offset = 3;
208 assert_se(dhcp6_option_parse(packet, 0, &offset, &optcode, &optlen, &optval) == -EBADMSG);
209
210 /* Tests for reading unaligned data. */
211 assert_se(buf = new(uint8_t, sizeof(packet)));
212 for (size_t i = 0; i <= 7; i++) {
213 memcpy(buf, packet + i, sizeof(packet) - i);
214 offset = 7 - i;
215 assert_se(dhcp6_option_parse(buf, sizeof(packet), &offset, &optcode, &optlen, &optval) >= 0);
216
217 assert_se(optcode == SD_DHCP6_OPTION_ORO);
218 assert_se(optlen == 7);
219 assert_se(optval == buf + 11 - i);
220 }
221
222 offset = 7;
223 assert_se(dhcp6_option_parse(packet, sizeof(packet), &offset, &optcode, &optlen, &optval) >= 0);
224
225 assert_se(optcode == SD_DHCP6_OPTION_ORO);
226 assert_se(optlen == 7);
227 assert_se(optval == packet + 11);
228
229 free(buf);
230 assert_se(buf = memdup(result, sizeof(result)));
231 pos = 7;
232 assert_se(dhcp6_option_append(&buf, &pos, optcode, optlen, optval) >= 0);
233
234 assert_se(dhcp6_option_parse(packet, sizeof(packet), &offset, &optcode, &optlen, &optval) >= 0);
235
236 assert_se(optcode == SD_DHCP6_OPTION_VENDOR_CLASS);
237 assert_se(optlen == 9);
238 assert_se(optval == packet + 22);
239
240 assert_se(dhcp6_option_append(&buf, &pos, optcode, optlen, optval) >= 0);
241
242 assert_se(memcmp(packet, buf, sizeof(packet)) == 0);
243 }
244
245 TEST(option_status) {
246 uint8_t option1[] = {
247 /* IA NA */
248 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d,
249 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
250 /* status option */
251 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
252 };
253 static const uint8_t option2[] = {
254 /* IA NA */
255 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d,
256 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
257 /* IA Addr */
258 0x00, 0x05, 0x00, 0x1e,
259 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
260 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
261 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
262 /* IA address status option */
263 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
264 };
265 static const uint8_t option3[] = {
266 /* IA NA */
267 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d,
268 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
269 /* IA Addr */
270 0x00, 0x05, 0x00, 0x24,
271 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
272 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
273 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
274 /* IA address status option */
275 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 'f', 'o',
276 'o', 'b', 'a', 'r',
277 };
278 static const uint8_t option4[] = {
279 /* IA PD */
280 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d,
281 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
282 /* IA PD Prefix */
283 0x00, 0x1a, 0x00, 0x1f,
284 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
285 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
286 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00,
288 /* PD prefix status option */
289 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
290 };
291 static const uint8_t option5[] = {
292 /* IA PD */
293 0x00, 0x19, 0x00, 0x52, 0x1a, 0x1d, 0x1a, 0x1d,
294 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
295 /* IA PD Prefix #1 */
296 0x00, 0x1a, 0x00, 0x1f,
297 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
298 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
299 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00,
301 /* PD prefix status option */
302 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
303 /* IA PD Prefix #2 */
304 0x00, 0x1a, 0x00, 0x1f,
305 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
306 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x0l, 0xd0,
307 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00,
309 /* PD prefix status option */
310 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
311 };
312 _cleanup_(dhcp6_ia_freep) DHCP6IA *ia = NULL;
313 DHCP6Option *option;
314 be32_t iaid;
315 int r;
316
317 memcpy(&iaid, option1 + 4, sizeof(iaid));
318
319 option = (DHCP6Option*) option1;
320 assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
321
322 r = dhcp6_option_parse_ia(NULL, 0, be16toh(option->code), be16toh(option->len), option->data, &ia);
323 assert_se(r == -ENOANO);
324
325 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
326 assert_se(r == -EINVAL);
327
328 option->len = htobe16(17);
329 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
330 assert_se(r == -EBADMSG);
331
332 option->len = htobe16(sizeof(DHCP6Option));
333 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
334 assert_se(r == -EBADMSG);
335
336 option = (DHCP6Option*) option2;
337 assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
338 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
339 assert_se(r == -ENODATA);
340
341 option = (DHCP6Option*) option3;
342 assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
343 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
344 assert_se(r >= 0);
345 assert_se(ia);
346 assert_se(ia->addresses);
347 ia = dhcp6_ia_free(ia);
348
349 option = (DHCP6Option*) option4;
350 assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
351 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
352 assert_se(r >= 0);
353 assert_se(ia);
354 assert_se(ia->addresses);
355 assert_se(memcmp(&ia->header.id, &option4[4], 4) == 0);
356 assert_se(memcmp(&ia->header.lifetime_t1, &option4[8], 4) == 0);
357 assert_se(memcmp(&ia->header.lifetime_t2, &option4[12], 4) == 0);
358 ia = dhcp6_ia_free(ia);
359
360 option = (DHCP6Option*) option5;
361 assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
362 r = dhcp6_option_parse_ia(NULL, iaid, be16toh(option->code), be16toh(option->len), option->data, &ia);
363 assert_se(r >= 0);
364 assert_se(ia);
365 assert_se(ia->addresses);
366 ia = dhcp6_ia_free(ia);
367 }
368
369 TEST(client_parse_message_issue_22099) {
370 static const uint8_t msg[] = {
371 /* Message type */
372 DHCP6_MESSAGE_REPLY,
373 /* Transaction ID */
374 0x7c, 0x4c, 0x16,
375 /* Rapid commit */
376 0x00, SD_DHCP6_OPTION_RAPID_COMMIT, 0x00, 0x00,
377 /* NTP servers */
378 0x00, SD_DHCP6_OPTION_NTP_SERVER, 0x00, 0x14,
379 /* NTP server (broken sub option and sub option length) */
380 0x01, 0x00, 0x10, 0x00,
381 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x15, 0xc8, 0xff, 0xfe, 0xef, 0x1e, 0x4e,
382 /* Client ID */
383 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
384 0x00, 0x02, /* DUID-EN */
385 0x00, 0x00, 0xab, 0x11, /* pen */
386 0x5c, 0x6b, 0x90, 0xec, 0xda, 0x95, 0x15, 0x45, /* id */
387 /* Server ID */
388 0x00, SD_DHCP6_OPTION_SERVERID, 0x00, 0x0a,
389 0x00, 0x03, /* DUID-LL */
390 0x00, 0x01, /* htype */
391 0xdc, 0x15, 0xc8, 0xef, 0x1e, 0x4e, /* haddr */
392 /* preference */
393 0x00, SD_DHCP6_OPTION_PREFERENCE, 0x00, 0x01,
394 0x00,
395 /* DNS servers */
396 0x00, SD_DHCP6_OPTION_DNS_SERVER, 0x00, 0x10,
397 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x15, 0xc8, 0xff, 0xfe, 0xef, 0x1e, 0x4e,
398 /* v6 pcp server */
399 0x00, SD_DHCP6_OPTION_V6_PCP_SERVER, 0x00, 0x10,
400 0x2a, 0x02, 0x81, 0x0d, 0x98, 0x80, 0x37, 0x00, 0xde, 0x15, 0xc8, 0xff, 0xfe, 0xef, 0x1e, 0x4e,
401 /* IA_NA */
402 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x28,
403 0xcc, 0x59, 0x11, 0x7b, /* iaid */
404 0x00, 0x00, 0x07, 0x08, /* lifetime T1 */
405 0x00, 0x00, 0x0b, 0x40, /* lifetime T2 */
406 /* IA_NA (iaaddr suboption) */
407 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
408 0x2a, 0x02, 0x81, 0x0d, 0x98, 0x80, 0x37, 0x00, 0x6a, 0x05, 0xca, 0xff, 0xfe, 0xf1, 0x51, 0x53, /* address */
409 0x00, 0x00, 0x0e, 0x10, /* preferred lifetime */
410 0x00, 0x00, 0x1c, 0x20, /* valid lifetime */
411 /* IA_PD */
412 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x29,
413 0xcc, 0x59, 0x11, 0x7b, /* iaid */
414 0x00, 0x00, 0x07, 0x08, /* lifetime T1 */
415 0x00, 0x00, 0x0b, 0x40, /* lifetime T2 */
416 /* IA_PD (iaprefix suboption) */
417 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
418 0x00, 0x00, 0x0e, 0x10, /* preferred lifetime */
419 0x00, 0x00, 0x1c, 0x20, /* valid lifetime */
420 0x3a, /* prefixlen */
421 0x2a, 0x02, 0x81, 0x0d, 0x98, 0x80, 0x37, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* prefix */
422 };
423 static const uint8_t duid[] = {
424 0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0x90, 0xec, 0xda, 0x95, 0x15, 0x45,
425 };
426 _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
427 _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
428
429 assert_se(sd_dhcp6_client_new(&client) >= 0);
430 assert_se(sd_dhcp6_client_set_iaid(client, 0xcc59117b) >= 0);
431 assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0);
432
433 assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
434 }
435
436 TEST(client_parse_message_issue_24002) {
437 static const uint8_t msg[] = {
438 /* Message Type */
439 0x07,
440 /* Transaction ID */
441 0x0e, 0xa5, 0x7c,
442 /* Client ID */
443 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
444 0x00, 0x02, /* DUID-EN */
445 0x00, 0x00, 0xab, 0x11, /* pen */
446 0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, /* id */
447 /* Server ID */
448 0x00, 0x02, 0x00, 0x1a,
449 0x00, 0x02, 0x00, 0x00, 0x05, 0x83, 0x30, 0x63, 0x3a, 0x38, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
450 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
451 /* IA_PD */
452 0x00, 0x19, 0x00, 0x29,
453 0xaa, 0xbb, 0xcc, 0xdd, /* iaid */
454 0x00, 0x00, 0x03, 0x84, /* lifetime (T1) */
455 0x00, 0x00, 0x05, 0xa0, /* lifetime (T2) */
456 /* IA_PD (iaprefix suboption) */
457 0x00, 0x1a, 0x00, 0x19,
458 0x00, 0x00, 0x07, 0x08, /* preferred lifetime */
459 0x00, 0x00, 0x38, 0x40, /* valid lifetime */
460 0x38, /* prefixlen */
461 0x20, 0x03, 0x00, 0xff, 0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* prefix */
462 /* Rapid commit */
463 0x00, 0x0e, 0x00, 0x00,
464 };
465 static const uint8_t duid[] = {
466 0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
467 };
468 _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
469 _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
470
471 assert_se(sd_dhcp6_client_new(&client) >= 0);
472 assert_se(sd_dhcp6_client_set_iaid(client, 0xaabbccdd) >= 0);
473 assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0);
474
475 assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
476 }
477
478 static const uint8_t msg_information_request[] = {
479 /* Message type */
480 DHCP6_MESSAGE_INFORMATION_REQUEST,
481 /* Transaction ID */
482 0x0f, 0xb4, 0xe5,
483 /* MUD URL */
484 /* ORO */
485 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x0c,
486 0x00, SD_DHCP6_OPTION_DNS_SERVER,
487 0x00, SD_DHCP6_OPTION_DOMAIN,
488 0x00, SD_DHCP6_OPTION_SNTP_SERVER,
489 0x00, SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME,
490 0x00, SD_DHCP6_OPTION_NTP_SERVER,
491 0x00, SD_DHCP6_OPTION_INF_MAX_RT,
492 /* Client ID */
493 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
494 CLIENT_ID_BYTES,
495 /* Extra options */
496 /* Elapsed time */
497 0x00, SD_DHCP6_OPTION_ELAPSED_TIME, 0x00, 0x02,
498 0x00, 0x00,
499 };
500
501 static const uint8_t msg_solicit[] = {
502 /* Message type */
503 DHCP6_MESSAGE_SOLICIT,
504 /* Transaction ID */
505 0x0f, 0xb4, 0xe5,
506 /* Rapid commit */
507 0x00, SD_DHCP6_OPTION_RAPID_COMMIT, 0x00, 0x00,
508 /* IA_NA */
509 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x0c,
510 IA_ID_BYTES,
511 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
512 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
513 /* IA_PD */
514 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x0c,
515 IA_ID_BYTES,
516 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
517 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
518 /* Client FQDN */
519 0x00, SD_DHCP6_OPTION_CLIENT_FQDN, 0x00, 0x11,
520 DHCP6_FQDN_FLAG_S,
521 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
522 /* User Class */
523 /* Vendor Class */
524 /* Vendor Options */
525 /* MUD URL */
526 /* ORO */
527 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x0a,
528 0x00, SD_DHCP6_OPTION_DNS_SERVER,
529 0x00, SD_DHCP6_OPTION_DOMAIN,
530 0x00, SD_DHCP6_OPTION_SNTP_SERVER,
531 0x00, SD_DHCP6_OPTION_NTP_SERVER,
532 0x00, SD_DHCP6_OPTION_SOL_MAX_RT,
533 /* Client ID */
534 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
535 CLIENT_ID_BYTES,
536 /* Extra options */
537 /* Elapsed time */
538 0x00, SD_DHCP6_OPTION_ELAPSED_TIME, 0x00, 0x02,
539 0x00, 0x00,
540 };
541
542 static const uint8_t msg_request[] = {
543 /* Message type */
544 DHCP6_MESSAGE_REQUEST,
545 /* Transaction ID */
546 0x00, 0x00, 0x00,
547 /* Server ID */
548 0x00, SD_DHCP6_OPTION_SERVERID, 0x00, 0x0e,
549 SERVER_ID_BYTES,
550 /* IA_NA */
551 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x44,
552 IA_ID_BYTES,
553 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
554 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
555 /* IA_NA (IAADDR suboption) */
556 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
557 IA_NA_ADDRESS1_BYTES,
558 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
559 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
560 /* IA_NA (IAADDR suboption) */
561 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
562 IA_NA_ADDRESS2_BYTES,
563 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
564 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
565 /* IA_PD */
566 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x46,
567 IA_ID_BYTES,
568 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
569 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
570 /* IA_PD (IA_PD_PREFIX suboption) */
571 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
572 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
573 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
574 0x40, /* prefixlen */
575 IA_PD_PREFIX1_BYTES,
576 /* IA_PD (IA_PD_PREFIX suboption) */
577 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
578 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
579 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
580 0x40, /* prefixlen */
581 IA_PD_PREFIX2_BYTES,
582 /* Client FQDN */
583 0x00, SD_DHCP6_OPTION_CLIENT_FQDN, 0x00, 0x11,
584 DHCP6_FQDN_FLAG_S,
585 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
586 /* User Class */
587 /* Vendor Class */
588 /* Vendor Options */
589 /* MUD URL */
590 /* ORO */
591 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
592 0x00, SD_DHCP6_OPTION_DNS_SERVER,
593 0x00, SD_DHCP6_OPTION_DOMAIN,
594 0x00, SD_DHCP6_OPTION_SNTP_SERVER,
595 0x00, SD_DHCP6_OPTION_NTP_SERVER,
596 /* Client ID */
597 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
598 CLIENT_ID_BYTES,
599 /* Extra options */
600 /* Elapsed time */
601 0x00, SD_DHCP6_OPTION_ELAPSED_TIME, 0x00, 0x02,
602 0x00, 0x00,
603 };
604
605 static const uint8_t msg_reply[] = {
606 /* Message type */
607 DHCP6_MESSAGE_REPLY,
608 /* Transaction ID */
609 0x0f, 0xb4, 0xe5,
610 /* Client ID */
611 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
612 CLIENT_ID_BYTES,
613 /* Server ID */
614 0x00, SD_DHCP6_OPTION_SERVERID, 0x00, 0x0e,
615 SERVER_ID_BYTES,
616 /* Rapid commit */
617 0x00, SD_DHCP6_OPTION_RAPID_COMMIT, 0x00, 0x01,
618 0x00,
619 /* IA_NA */
620 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x66,
621 IA_ID_BYTES,
622 0x00, 0x00, 0x00, 0x50, /* lifetime T1 */
623 0x00, 0x00, 0x00, 0x78, /* lifetime T2 */
624 /* IA_NA (IAADDR suboption) */
625 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
626 IA_NA_ADDRESS2_BYTES,
627 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
628 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
629 /* IA_NA (IAADDR suboption) */
630 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
631 IA_NA_ADDRESS1_BYTES,
632 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
633 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
634 /* IA_NA (status code suboption) */
635 0x00, SD_DHCP6_OPTION_STATUS_CODE, 0x00, 0x1e,
636 0x00, 0x00, /* status code */
637 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, 0x65,
638 0x72, 0x65, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, /* status message */
639 /* IA_PD */
640 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x46,
641 IA_ID_BYTES,
642 0x00, 0x00, 0x00, 0x50, /* lifetime T1 */
643 0x00, 0x00, 0x00, 0x78, /* lifetime T2 */
644 /* IA_PD (IA_PD_PREFIX suboption) */
645 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
646 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
647 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
648 0x40, /* prefixlen */
649 IA_PD_PREFIX2_BYTES,
650 /* IA_PD (IA_PD_PREFIX suboption) */
651 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
652 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
653 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
654 0x40, /* prefixlen */
655 IA_PD_PREFIX1_BYTES,
656 /* DNS servers */
657 0x00, SD_DHCP6_OPTION_DNS_SERVER, 0x00, 0x20,
658 DNS1_BYTES,
659 DNS2_BYTES,
660 /* SNTP servers */
661 0x00, SD_DHCP6_OPTION_SNTP_SERVER, 0x00, 0x20,
662 SNTP1_BYTES,
663 SNTP2_BYTES,
664 /* NTP servers */
665 0x00, SD_DHCP6_OPTION_NTP_SERVER, 0x00, 0x37,
666 /* NTP server (address suboption) */
667 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR, 0x00, 0x10,
668 NTP1_BYTES,
669 /* NTP server (address suboption) */
670 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR, 0x00, 0x10,
671 NTP2_BYTES,
672 /* NTP server (fqdn suboption) */
673 0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
674 0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
675 /* Domain list */
676 0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
677 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
678 /* Client FQDN */
679 0x00, SD_DHCP6_OPTION_CLIENT_FQDN, 0x00, 0x12,
680 0x01, 0x06, 'c', 'l', 'i', 'e', 'n', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a',
681 };
682
683 static const uint8_t msg_advertise[] = {
684 /* Message type */
685 DHCP6_MESSAGE_ADVERTISE,
686 /* Transaction ID */
687 0x0f, 0xb4, 0xe5,
688 /* Client ID */
689 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
690 CLIENT_ID_BYTES,
691 /* Server ID */
692 0x00, SD_DHCP6_OPTION_SERVERID, 0x00, 0x0e,
693 SERVER_ID_BYTES,
694 /* Preference */
695 0x00, SD_DHCP6_OPTION_PREFERENCE, 0x00, 0x01,
696 0xff,
697 /* IA_NA */
698 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x7a,
699 IA_ID_BYTES,
700 0x00, 0x00, 0x00, 0x50, /* lifetime T1 */
701 0x00, 0x00, 0x00, 0x78, /* lifetime T2 */
702 /* IA_NA (IAADDR suboption) */
703 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
704 IA_NA_ADDRESS2_BYTES, /* address */
705 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
706 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
707 /* IA_NA (IAADDR suboption) */
708 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
709 IA_NA_ADDRESS1_BYTES, /* address */
710 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
711 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
712 /* IA_NA (status code suboption) */
713 0x00, SD_DHCP6_OPTION_STATUS_CODE, 0x00, 0x32,
714 0x00, 0x00, /* status code */
715 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28, 0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
716 0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
717 0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68, /* status message */
718 /* IA_PD */
719 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x46,
720 IA_ID_BYTES,
721 0x00, 0x00, 0x00, 0x50, /* lifetime T1 */
722 0x00, 0x00, 0x00, 0x78, /* lifetime T2 */
723 /* IA_PD (IA_PD_PREFIX suboption) */
724 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
725 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
726 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
727 0x40, /* prefixlen */
728 IA_PD_PREFIX2_BYTES,
729 /* IA_PD (IA_PD_PREFIX suboption) */
730 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
731 0x00, 0x00, 0x00, 0x96, /* preferred lifetime */
732 0x00, 0x00, 0x00, 0xb4, /* valid lifetime */
733 0x40, /* prefixlen */
734 IA_PD_PREFIX1_BYTES,
735 /* DNS servers */
736 0x00, SD_DHCP6_OPTION_DNS_SERVER, 0x00, 0x20,
737 DNS1_BYTES,
738 DNS2_BYTES,
739 /* SNTP servers */
740 0x00, SD_DHCP6_OPTION_SNTP_SERVER, 0x00, 0x20,
741 SNTP1_BYTES,
742 SNTP2_BYTES,
743 /* NTP servers */
744 0x00, SD_DHCP6_OPTION_NTP_SERVER, 0x00, 0x37,
745 /* NTP server (address suboption) */
746 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR, 0x00, 0x10,
747 NTP1_BYTES,
748 /* NTP server (address suboption) */
749 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR, 0x00, 0x10,
750 NTP2_BYTES,
751 /* NTP server (fqdn suboption) */
752 0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
753 0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
754 /* Domain list */
755 0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
756 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
757 /* Client FQDN */
758 0x00, SD_DHCP6_OPTION_CLIENT_FQDN, 0x00, 0x12,
759 0x01, 0x06, 'c', 'l', 'i', 'e', 'n', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a',
760 };
761
762 static void test_client_verify_information_request(const DHCP6Message *msg, size_t len) {
763 log_debug("/* %s */", __func__);
764
765 assert_se(len == sizeof(msg_information_request));
766 /* The elapsed time value is not deterministic. Skip it. */
767 assert_se(memcmp(msg, msg_information_request, len - sizeof(be16_t)) == 0);
768 }
769
770 static void test_client_verify_solicit(const DHCP6Message *msg, size_t len) {
771 log_debug("/* %s */", __func__);
772
773 assert_se(len == sizeof(msg_solicit));
774 /* The elapsed time value is not deterministic. Skip it. */
775 assert_se(memcmp(msg, msg_solicit, len - sizeof(be16_t)) == 0);
776 }
777
778 static void test_client_verify_request(const DHCP6Message *msg, size_t len) {
779 log_debug("/* %s */", __func__);
780
781 assert_se(len == sizeof(msg_request));
782 assert_se(msg->type == DHCP6_MESSAGE_REQUEST);
783 /* The transaction ID and elapsed time value are not deterministic. Skip them. */
784 assert_se(memcmp(msg->options, msg_request + offsetof(DHCP6Message, options), len - offsetof(DHCP6Message, options) - sizeof(be16_t)) == 0);
785 }
786
787 static void test_lease_common(sd_dhcp6_client *client) {
788 sd_dhcp6_lease *lease;
789 const struct in6_addr *addrs;
790 const char *str;
791 char **strv;
792 uint8_t *id;
793 size_t len;
794
795 assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
796
797 assert_se(dhcp6_lease_get_clientid(lease, &id, &len) >= 0);
798 assert_se(memcmp_nn(id, len, client_id, sizeof(client_id)) == 0);
799
800 assert_se(sd_dhcp6_lease_get_domains(lease, &strv) == 1);
801 assert_se(streq(strv[0], "lab.intra"));
802 assert_se(!strv[1]);
803
804 assert_se(sd_dhcp6_lease_get_fqdn(lease, &str) >= 0);
805 assert_se(streq(str, "client.lab.intra"));
806
807 assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 2);
808 assert_se(in6_addr_equal(&addrs[0], &dns1));
809 assert_se(in6_addr_equal(&addrs[1], &dns2));
810
811 assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 2);
812 assert_se(in6_addr_equal(&addrs[0], &ntp1));
813 assert_se(in6_addr_equal(&addrs[1], &ntp2));
814
815 assert_se(sd_dhcp6_lease_get_ntp_fqdn(lease, &strv) == 1);
816 assert_se(streq(strv[0], "ntp.intra"));
817 assert_se(!strv[1]);
818
819 assert_se(lease->sntp_count == 2);
820 assert_se(in6_addr_equal(&lease->sntp[0], &sntp1));
821 assert_se(in6_addr_equal(&lease->sntp[1], &sntp2));
822 }
823
824 static void test_lease_managed(sd_dhcp6_client *client) {
825 sd_dhcp6_lease *lease;
826 struct in6_addr addr;
827 uint32_t lt_pref, lt_valid;
828 uint8_t *id, prefixlen;
829 size_t len;
830
831 assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
832
833 assert_se(dhcp6_lease_get_serverid(lease, &id, &len) >= 0);
834 assert_se(memcmp_nn(id, len, server_id, sizeof(server_id)) == 0);
835
836 sd_dhcp6_lease_reset_address_iter(lease);
837 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) >= 0);
838 assert_se(in6_addr_equal(&addr, &ia_na_address1));
839 assert_se(lt_pref == 150);
840 assert_se(lt_valid == 180);
841 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) >= 0);
842 assert_se(in6_addr_equal(&addr, &ia_na_address2));
843 assert_se(lt_pref == 150);
844 assert_se(lt_valid == 180);
845 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENODATA);
846
847 sd_dhcp6_lease_reset_address_iter(lease);
848 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) >= 0);
849 assert_se(in6_addr_equal(&addr, &ia_na_address1));
850 assert_se(lt_pref == 150);
851 assert_se(lt_valid == 180);
852 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) >= 0);
853 assert_se(in6_addr_equal(&addr, &ia_na_address2));
854 assert_se(lt_pref == 150);
855 assert_se(lt_valid == 180);
856 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENODATA);
857
858 sd_dhcp6_lease_reset_pd_prefix_iter(lease);
859 assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, &lt_pref, &lt_valid) >= 0);
860 assert_se(in6_addr_equal(&addr, &ia_pd_prefix1));
861 assert_se(prefixlen == 64);
862 assert_se(lt_pref == 150);
863 assert_se(lt_valid == 180);
864 assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, &lt_pref, &lt_valid) >= 0);
865 assert_se(in6_addr_equal(&addr, &ia_pd_prefix2));
866 assert_se(prefixlen == 64);
867 assert_se(lt_pref == 150);
868 assert_se(lt_valid == 180);
869 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENODATA);
870
871 sd_dhcp6_lease_reset_pd_prefix_iter(lease);
872 assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, &lt_pref, &lt_valid) >= 0);
873 assert_se(in6_addr_equal(&addr, &ia_pd_prefix1));
874 assert_se(prefixlen == 64);
875 assert_se(lt_pref == 150);
876 assert_se(lt_valid == 180);
877 assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, &lt_pref, &lt_valid) >= 0);
878 assert_se(in6_addr_equal(&addr, &ia_pd_prefix2));
879 assert_se(prefixlen == 64);
880 assert_se(lt_pref == 150);
881 assert_se(lt_valid == 180);
882 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENODATA);
883
884 test_lease_common(client);
885 }
886
887 static void test_client_callback(sd_dhcp6_client *client, int event, void *userdata) {
888 switch (event) {
889 case SD_DHCP6_CLIENT_EVENT_STOP:
890 log_debug("/* %s (event=stop) */", __func__);
891 return;
892
893 case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
894 log_debug("/* %s (event=information-request) */", __func__);
895
896 assert_se(test_client_sent_message_count == 1);
897
898 test_lease_common(client);
899
900 assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
901 assert_se(sd_dhcp6_client_start(client) >= 0);
902 assert_se(dhcp6_client_set_transaction_id(client, ((const DHCP6Message*) msg_advertise)->transaction_id) >= 0);
903 break;
904
905 case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
906 log_debug("/* %s (event=ip-acquire) */", __func__);
907
908 assert_se(IN_SET(test_client_sent_message_count, 3, 4));
909
910 test_lease_managed(client);
911
912 switch (test_client_sent_message_count) {
913 case 3:
914 assert_se(sd_dhcp6_client_stop(client) >= 0);
915 assert_se(sd_dhcp6_client_start(client) >= 0);
916 assert_se(dhcp6_client_set_transaction_id(client, ((const DHCP6Message*) msg_reply)->transaction_id) >= 0);
917 break;
918
919 case 4:
920 assert_se(sd_event_exit(sd_dhcp6_client_get_event(client), 0) >= 0);
921 break;
922
923 default:
924 assert_not_reached();
925 }
926
927 break;
928
929 case DHCP6_CLIENT_EVENT_TEST_ADVERTISED: {
930 sd_dhcp6_lease *lease;
931 uint8_t preference;
932
933 log_debug("/* %s (event=test-advertised) */", __func__);
934
935 assert_se(test_client_sent_message_count == 2);
936
937 test_lease_managed(client);
938
939 assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
940 assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
941 assert_se(preference == 0xff);
942
943 assert_se(dhcp6_client_set_transaction_id(client, ((const DHCP6Message*) msg_reply)->transaction_id) >= 0);
944 break;
945 }
946 default:
947 assert_not_reached();
948 }
949 }
950
951 int dhcp6_network_send_udp_socket(int s, struct in6_addr *a, const void *packet, size_t len) {
952 log_debug("/* %s(count=%u) */", __func__, test_client_sent_message_count);
953
954 assert_se(a);
955 assert_se(in6_addr_equal(a, &mcast_address));
956 assert_se(packet);
957 assert_se(len >= sizeof(DHCP6Message));
958
959 switch (test_client_sent_message_count) {
960 case 0:
961 test_client_verify_information_request(packet, len);
962 assert_se(write(test_fd[1], msg_reply, sizeof(msg_reply)) == sizeof(msg_reply));
963 break;
964
965 case 1:
966 test_client_verify_solicit(packet, len);
967 assert_se(write(test_fd[1], msg_advertise, sizeof(msg_advertise)) == sizeof(msg_advertise));
968 break;
969
970 case 2:
971 test_client_callback(client_ref, DHCP6_CLIENT_EVENT_TEST_ADVERTISED, NULL);
972 test_client_verify_request(packet, len);
973 assert_se(write(test_fd[1], msg_reply, sizeof(msg_reply)) == sizeof(msg_reply));
974 break;
975
976 case 3:
977 test_client_verify_solicit(packet, len);
978 assert_se(write(test_fd[1], msg_reply, sizeof(msg_reply)) == sizeof(msg_reply));
979 break;
980
981 default:
982 assert_not_reached();
983 }
984
985 test_client_sent_message_count++;
986 return len;
987 }
988
989 int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *a) {
990 assert_se(ifindex == test_ifindex);
991 assert_se(a);
992 assert_se(in6_addr_equal(a, &local_address));
993
994 assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
995 return TAKE_FD(test_fd[0]);
996 }
997
998 TEST(dhcp6_client) {
999 _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
1000 _cleanup_(sd_event_unrefp) sd_event *e = NULL;
1001
1002 assert_se(sd_event_new(&e) >= 0);
1003 assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME,
1004 2 * USEC_PER_SEC, 0,
1005 NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0);
1006
1007 assert_se(sd_dhcp6_client_new(&client) >= 0);
1008 assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
1009 assert_se(sd_dhcp6_client_set_ifindex(client, test_ifindex) == 0);
1010 assert_se(sd_dhcp6_client_set_local_address(client, &local_address) >= 0);
1011 assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") >= 0);
1012 assert_se(sd_dhcp6_client_set_iaid(client, unaligned_read_be32((uint8_t[]) { IA_ID_BYTES })) >= 0);
1013 dhcp6_client_set_test_mode(client, true);
1014
1015 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
1016 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0);
1017 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) >= 0);
1018 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVER) >= 0);
1019
1020 assert_se(sd_dhcp6_client_set_information_request(client, true) >= 0);
1021 assert_se(sd_dhcp6_client_set_callback(client, test_client_callback, NULL) >= 0);
1022
1023 assert_se(sd_dhcp6_client_start(client) >= 0);
1024
1025 assert_se(dhcp6_client_set_transaction_id(client, ((const DHCP6Message*) msg_reply)->transaction_id) >= 0);
1026
1027 assert_se(client_ref = sd_dhcp6_client_ref(client));
1028
1029 assert_se(sd_event_loop(e) >= 0);
1030
1031 assert_se(test_client_sent_message_count == 4);
1032
1033 assert_se(!sd_dhcp6_client_unref(client_ref));
1034 test_fd[1] = safe_close(test_fd[1]);
1035 }
1036
1037 DEFINE_TEST_MAIN(LOG_DEBUG);