1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2014 Intel Corporation. All rights reserved.
6 #include <net/ethernet.h>
7 #include <net/if_arp.h>
10 #include <sys/types.h>
13 #include "sd-dhcp6-client.h"
16 #include "dhcp-identifier.h"
17 #include "dhcp6-internal.h"
18 #include "dhcp6-lease-internal.h"
19 #include "dhcp6-protocol.h"
22 #include "memory-util.h"
23 #include "socket-util.h"
24 #include "string-util.h"
27 #include "time-util.h"
29 #define DHCP6_CLIENT_EVENT_TEST_ADVERTISED 77
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
41 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
43 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
45 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
47 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04
49 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05
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
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' },
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
;
82 _cleanup_(sd_dhcp6_client_unrefp
) sd_dhcp6_client
*client
= NULL
;
85 assert_se(sd_dhcp6_client_new(&client
) >= 0);
88 assert_se(sd_dhcp6_client_set_ifindex(client
, 15) == 0);
89 assert_se(sd_dhcp6_client_set_ifindex(client
, 42) >= 0);
91 assert_se(sd_dhcp6_client_set_mac(client
, mac
.ether_addr_octet
, sizeof(mac
), ARPHRD_ETHER
) >= 0);
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
);
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
);
110 assert_se(sd_dhcp6_client_set_information_request(client
, 1) >= 0);
112 assert_se(sd_dhcp6_client_get_information_request(client
, &v
) >= 0);
114 assert_se(sd_dhcp6_client_set_information_request(client
, 0) >= 0);
116 assert_se(sd_dhcp6_client_get_information_request(client
, &v
) >= 0);
120 assert_se(sd_dhcp6_client_get_address_request(client
, &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);
127 assert_se(sd_dhcp6_client_set_address_request(client
, 1) >= 0);
128 assert_se(sd_dhcp6_client_get_address_request(client
, &v
) >= 0);
131 assert_se(sd_dhcp6_client_set_address_request(client
, 1) >= 0);
132 assert_se(sd_dhcp6_client_set_prefix_delegation(client
, 1) >= 0);
134 assert_se(sd_dhcp6_client_get_address_request(client
, &v
) >= 0);
137 assert_se(sd_dhcp6_client_get_prefix_delegation(client
, &v
) >= 0);
140 assert_se(sd_dhcp6_client_set_callback(client
, NULL
, NULL
) >= 0);
142 assert_se(sd_dhcp6_client_detach_event(client
) >= 0);
146 _cleanup_free_
char *domain
= NULL
;
147 _cleanup_strv_free_
char **list
= NULL
;
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);
153 assert_se(streq(domain
, "example.com"));
154 domain
= mfree(domain
);
156 data
= (uint8_t []) { 4, 't', 'e', 's', 't' };
157 assert_se(dhcp6_option_parse_domainname(data
, 5, &domain
) >= 0);
159 assert_se(streq(domain
, "test"));
160 domain
= mfree(domain
);
162 data
= (uint8_t []) { 0 };
163 assert_se(dhcp6_option_parse_domainname(data
, 1, &domain
) < 0);
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);
169 assert_se(streq(list
[0], "example.com"));
170 assert_se(streq(list
[1], "foobar"));
172 list
= strv_free(list
);
174 data
= (uint8_t []) { 1, 'a', 0, 20, 'b', 'c' };
175 assert_se(dhcp6_option_parse_domainname_list(data
, 6, &list
) < 0);
177 data
= (uint8_t []) { 0 , 0 };
178 assert_se(dhcp6_option_parse_domainname_list(data
, 2, &list
) < 0);
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',
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,
197 _cleanup_free_
uint8_t *buf
= NULL
;
198 size_t offset
, pos
, optlen
;
199 const uint8_t *optval
;
202 assert_se(sizeof(packet
) == sizeof(result
));
205 assert_se(dhcp6_option_parse(packet
, 0, &offset
, &optcode
, &optlen
, &optval
) == -EBADMSG
);
208 assert_se(dhcp6_option_parse(packet
, 0, &offset
, &optcode
, &optlen
, &optval
) == -EBADMSG
);
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
);
215 assert_se(dhcp6_option_parse(buf
, sizeof(packet
), &offset
, &optcode
, &optlen
, &optval
) >= 0);
217 assert_se(optcode
== SD_DHCP6_OPTION_ORO
);
218 assert_se(optlen
== 7);
219 assert_se(optval
== buf
+ 11 - i
);
223 assert_se(dhcp6_option_parse(packet
, sizeof(packet
), &offset
, &optcode
, &optlen
, &optval
) >= 0);
225 assert_se(optcode
== SD_DHCP6_OPTION_ORO
);
226 assert_se(optlen
== 7);
227 assert_se(optval
== packet
+ 11);
230 assert_se(buf
= memdup(result
, sizeof(result
)));
232 assert_se(dhcp6_option_append(&buf
, &pos
, optcode
, optlen
, optval
) >= 0);
234 assert_se(dhcp6_option_parse(packet
, sizeof(packet
), &offset
, &optcode
, &optlen
, &optval
) >= 0);
236 assert_se(optcode
== SD_DHCP6_OPTION_VENDOR_CLASS
);
237 assert_se(optlen
== 9);
238 assert_se(optval
== packet
+ 22);
240 assert_se(dhcp6_option_append(&buf
, &pos
, optcode
, optlen
, optval
) >= 0);
242 assert_se(memcmp(packet
, buf
, sizeof(packet
)) == 0);
245 TEST(option_status
) {
246 uint8_t option1
[] = {
248 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d,
249 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
251 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
253 static const uint8_t option2
[] = {
255 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d,
256 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
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,
265 static const uint8_t option3
[] = {
267 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d,
268 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
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',
278 static const uint8_t option4
[] = {
280 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d,
281 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
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,
288 /* PD prefix status option */
289 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
291 static const uint8_t option5
[] = {
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,
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,
309 /* PD prefix status option */
310 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
312 _cleanup_(dhcp6_ia_freep
) DHCP6IA
*ia
= NULL
;
317 memcpy(&iaid
, option1
+ 4, sizeof(iaid
));
319 option
= (DHCP6Option
*) option1
;
320 assert_se(sizeof(option1
) == sizeof(DHCP6Option
) + be16toh(option
->len
));
322 r
= dhcp6_option_parse_ia(NULL
, 0, be16toh(option
->code
), be16toh(option
->len
), option
->data
, &ia
);
323 assert_se(r
== -ENOANO
);
325 r
= dhcp6_option_parse_ia(NULL
, iaid
, be16toh(option
->code
), be16toh(option
->len
), option
->data
, &ia
);
326 assert_se(r
== -EINVAL
);
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
);
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
);
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
);
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
);
346 assert_se(ia
->addresses
);
347 ia
= dhcp6_ia_free(ia
);
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
);
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
);
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
);
365 assert_se(ia
->addresses
);
366 ia
= dhcp6_ia_free(ia
);
369 TEST(client_parse_message_issue_22099
) {
370 static const uint8_t msg
[] = {
376 0x00, SD_DHCP6_OPTION_RAPID_COMMIT
, 0x00, 0x00,
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,
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 */
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 */
393 0x00, SD_DHCP6_OPTION_PREFERENCE
, 0x00, 0x01,
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,
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,
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 */
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 */
423 static const uint8_t duid
[] = {
424 0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0x90, 0xec, 0xda, 0x95, 0x15, 0x45,
426 _cleanup_(sd_dhcp6_client_unrefp
) sd_dhcp6_client
*client
= NULL
;
427 _cleanup_(sd_dhcp6_lease_unrefp
) sd_dhcp6_lease
*lease
= NULL
;
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);
433 assert_se(dhcp6_lease_new_from_message(client
, (const DHCP6Message
*) msg
, sizeof(msg
), NULL
, NULL
, &lease
) >= 0);
436 TEST(client_parse_message_issue_24002
) {
437 static const uint8_t msg
[] = {
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 */
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,
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 */
463 0x00, 0x0e, 0x00, 0x00,
465 static const uint8_t duid
[] = {
466 0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
468 _cleanup_(sd_dhcp6_client_unrefp
) sd_dhcp6_client
*client
= NULL
;
469 _cleanup_(sd_dhcp6_lease_unrefp
) sd_dhcp6_lease
*lease
= NULL
;
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);
475 assert_se(dhcp6_lease_new_from_message(client
, (const DHCP6Message
*) msg
, sizeof(msg
), NULL
, NULL
, &lease
) >= 0);
478 static const uint8_t msg_information_request
[] = {
480 DHCP6_MESSAGE_INFORMATION_REQUEST
,
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
,
493 0x00, SD_DHCP6_OPTION_CLIENTID
, 0x00, 0x0e,
497 0x00, SD_DHCP6_OPTION_ELAPSED_TIME
, 0x00, 0x02,
501 static const uint8_t msg_solicit
[] = {
503 DHCP6_MESSAGE_SOLICIT
,
507 0x00, SD_DHCP6_OPTION_RAPID_COMMIT
, 0x00, 0x00,
509 0x00, SD_DHCP6_OPTION_IA_NA
, 0x00, 0x0c,
511 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
512 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
514 0x00, SD_DHCP6_OPTION_IA_PD
, 0x00, 0x0c,
516 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
517 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
519 0x00, SD_DHCP6_OPTION_CLIENT_FQDN
, 0x00, 0x11,
521 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
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
,
534 0x00, SD_DHCP6_OPTION_CLIENTID
, 0x00, 0x0e,
538 0x00, SD_DHCP6_OPTION_ELAPSED_TIME
, 0x00, 0x02,
542 static const uint8_t msg_request
[] = {
544 DHCP6_MESSAGE_REQUEST
,
548 0x00, SD_DHCP6_OPTION_SERVERID
, 0x00, 0x0e,
551 0x00, SD_DHCP6_OPTION_IA_NA
, 0x00, 0x44,
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 */
566 0x00, SD_DHCP6_OPTION_IA_PD
, 0x00, 0x46,
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 */
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 */
583 0x00, SD_DHCP6_OPTION_CLIENT_FQDN
, 0x00, 0x11,
585 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
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
,
597 0x00, SD_DHCP6_OPTION_CLIENTID
, 0x00, 0x0e,
601 0x00, SD_DHCP6_OPTION_ELAPSED_TIME
, 0x00, 0x02,
605 static const uint8_t msg_reply
[] = {
611 0x00, SD_DHCP6_OPTION_CLIENTID
, 0x00, 0x0e,
614 0x00, SD_DHCP6_OPTION_SERVERID
, 0x00, 0x0e,
617 0x00, SD_DHCP6_OPTION_RAPID_COMMIT
, 0x00, 0x01,
620 0x00, SD_DHCP6_OPTION_IA_NA
, 0x00, 0x66,
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 */
640 0x00, SD_DHCP6_OPTION_IA_PD
, 0x00, 0x46,
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 */
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 */
657 0x00, SD_DHCP6_OPTION_DNS_SERVER
, 0x00, 0x20,
661 0x00, SD_DHCP6_OPTION_SNTP_SERVER
, 0x00, 0x20,
665 0x00, SD_DHCP6_OPTION_NTP_SERVER
, 0x00, 0x37,
666 /* NTP server (address suboption) */
667 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR
, 0x00, 0x10,
669 /* NTP server (address suboption) */
670 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR
, 0x00, 0x10,
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,
676 0x00, SD_DHCP6_OPTION_DOMAIN
, 0x00, 0x0b,
677 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
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',
683 static const uint8_t msg_advertise
[] = {
685 DHCP6_MESSAGE_ADVERTISE
,
689 0x00, SD_DHCP6_OPTION_CLIENTID
, 0x00, 0x0e,
692 0x00, SD_DHCP6_OPTION_SERVERID
, 0x00, 0x0e,
695 0x00, SD_DHCP6_OPTION_PREFERENCE
, 0x00, 0x01,
698 0x00, SD_DHCP6_OPTION_IA_NA
, 0x00, 0x7a,
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 */
719 0x00, SD_DHCP6_OPTION_IA_PD
, 0x00, 0x46,
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 */
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 */
736 0x00, SD_DHCP6_OPTION_DNS_SERVER
, 0x00, 0x20,
740 0x00, SD_DHCP6_OPTION_SNTP_SERVER
, 0x00, 0x20,
744 0x00, SD_DHCP6_OPTION_NTP_SERVER
, 0x00, 0x37,
745 /* NTP server (address suboption) */
746 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR
, 0x00, 0x10,
748 /* NTP server (address suboption) */
749 0x00, DHCP6_NTP_SUBOPTION_SRV_ADDR
, 0x00, 0x10,
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,
755 0x00, SD_DHCP6_OPTION_DOMAIN
, 0x00, 0x0b,
756 0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
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',
762 static void test_client_verify_information_request(const DHCP6Message
*msg
, size_t len
) {
763 log_debug("/* %s */", __func__
);
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);
770 static void test_client_verify_solicit(const DHCP6Message
*msg
, size_t len
) {
771 log_debug("/* %s */", __func__
);
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);
778 static void test_client_verify_request(const DHCP6Message
*msg
, size_t len
) {
779 log_debug("/* %s */", __func__
);
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);
787 static void test_lease_common(sd_dhcp6_client
*client
) {
788 sd_dhcp6_lease
*lease
;
789 const struct in6_addr
*addrs
;
795 assert_se(sd_dhcp6_client_get_lease(client
, &lease
) >= 0);
797 assert_se(dhcp6_lease_get_clientid(lease
, &id
, &len
) >= 0);
798 assert_se(memcmp_nn(id
, len
, client_id
, sizeof(client_id
)) == 0);
800 assert_se(sd_dhcp6_lease_get_domains(lease
, &strv
) == 1);
801 assert_se(streq(strv
[0], "lab.intra"));
804 assert_se(sd_dhcp6_lease_get_fqdn(lease
, &str
) >= 0);
805 assert_se(streq(str
, "client.lab.intra"));
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
));
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
));
815 assert_se(sd_dhcp6_lease_get_ntp_fqdn(lease
, &strv
) == 1);
816 assert_se(streq(strv
[0], "ntp.intra"));
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
));
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
;
831 assert_se(sd_dhcp6_client_get_lease(client
, &lease
) >= 0);
833 assert_se(dhcp6_lease_get_serverid(lease
, &id
, &len
) >= 0);
834 assert_se(memcmp_nn(id
, len
, server_id
, sizeof(server_id
)) == 0);
836 sd_dhcp6_lease_reset_address_iter(lease
);
837 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
, <_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
, <_pref
, <_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
, <_pref
, <_valid
) == -ENODATA
);
847 sd_dhcp6_lease_reset_address_iter(lease
);
848 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
, <_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
, <_pref
, <_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
, <_pref
, <_valid
) == -ENODATA
);
858 sd_dhcp6_lease_reset_pd_prefix_iter(lease
);
859 assert_se(sd_dhcp6_lease_get_pd(lease
, &addr
, &prefixlen
, <_pref
, <_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
, <_pref
, <_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
, <_pref
, <_valid
) == -ENODATA
);
871 sd_dhcp6_lease_reset_pd_prefix_iter(lease
);
872 assert_se(sd_dhcp6_lease_get_pd(lease
, &addr
, &prefixlen
, <_pref
, <_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
, <_pref
, <_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
, <_pref
, <_valid
) == -ENODATA
);
884 test_lease_common(client
);
887 static void test_client_callback(sd_dhcp6_client
*client
, int event
, void *userdata
) {
889 case SD_DHCP6_CLIENT_EVENT_STOP
:
890 log_debug("/* %s (event=stop) */", __func__
);
893 case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST
:
894 log_debug("/* %s (event=information-request) */", __func__
);
896 assert_se(test_client_sent_message_count
== 1);
898 test_lease_common(client
);
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);
905 case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE
:
906 log_debug("/* %s (event=ip-acquire) */", __func__
);
908 assert_se(IN_SET(test_client_sent_message_count
, 3, 4));
910 test_lease_managed(client
);
912 switch (test_client_sent_message_count
) {
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);
920 assert_se(sd_event_exit(sd_dhcp6_client_get_event(client
), 0) >= 0);
924 assert_not_reached();
929 case DHCP6_CLIENT_EVENT_TEST_ADVERTISED
: {
930 sd_dhcp6_lease
*lease
;
933 log_debug("/* %s (event=test-advertised) */", __func__
);
935 assert_se(test_client_sent_message_count
== 2);
937 test_lease_managed(client
);
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);
943 assert_se(dhcp6_client_set_transaction_id(client
, ((const DHCP6Message
*) msg_reply
)->transaction_id
) >= 0);
947 assert_not_reached();
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
);
955 assert_se(in6_addr_equal(a
, &mcast_address
));
957 assert_se(len
>= sizeof(DHCP6Message
));
959 switch (test_client_sent_message_count
) {
961 test_client_verify_information_request(packet
, len
);
962 assert_se(write(test_fd
[1], msg_reply
, sizeof(msg_reply
)) == sizeof(msg_reply
));
966 test_client_verify_solicit(packet
, len
);
967 assert_se(write(test_fd
[1], msg_advertise
, sizeof(msg_advertise
)) == sizeof(msg_advertise
));
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
));
977 test_client_verify_solicit(packet
, len
);
978 assert_se(write(test_fd
[1], msg_reply
, sizeof(msg_reply
)) == sizeof(msg_reply
));
982 assert_not_reached();
985 test_client_sent_message_count
++;
989 int dhcp6_network_bind_udp_socket(int ifindex
, struct in6_addr
*a
) {
990 assert_se(ifindex
== test_ifindex
);
992 assert_se(in6_addr_equal(a
, &local_address
));
994 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) >= 0);
995 return TAKE_FD(test_fd
[0]);
999 _cleanup_(sd_dhcp6_client_unrefp
) sd_dhcp6_client
*client
= NULL
;
1000 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
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);
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);
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);
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);
1023 assert_se(sd_dhcp6_client_start(client
) >= 0);
1025 assert_se(dhcp6_client_set_transaction_id(client
, ((const DHCP6Message
*) msg_reply
)->transaction_id
) >= 0);
1027 assert_se(client_ref
= sd_dhcp6_client_ref(client
));
1029 assert_se(sd_event_loop(e
) >= 0);
1031 assert_se(test_client_sent_message_count
== 4);
1033 assert_se(!sd_dhcp6_client_unref(client_ref
));
1034 test_fd
[1] = safe_close(test_fd
[1]);
1037 DEFINE_TEST_MAIN(LOG_DEBUG
);