]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-dhcp6-client.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / libsystemd-network / test-dhcp6-client.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
813e3a6f 2/***
810adae9 3 Copyright © 2014 Intel Corporation. All rights reserved.
813e3a6f
PF
4***/
5
07630cea 6#include <net/ethernet.h>
8f815e8b 7#include <net/if_arp.h>
813e3a6f
PF
8#include <stdbool.h>
9#include <stdio.h>
07630cea 10#include <sys/types.h>
2ea8857e 11#include <unistd.h>
813e3a6f 12
07630cea 13#include "sd-dhcp6-client.h"
813e3a6f 14#include "sd-event.h"
813e3a6f 15
f12ed3bf 16#include "dhcp6-internal.h"
859cca44 17#include "dhcp6-lease-internal.h"
07630cea 18#include "dhcp6-protocol.h"
3ffd4af2 19#include "fd-util.h"
07630cea 20#include "macro.h"
0a970718 21#include "memory-util.h"
07630cea 22#include "socket-util.h"
c43eea9f
BG
23#include "string-util.h"
24#include "strv.h"
6d7c4033 25#include "tests.h"
0a970718 26#include "time-util.h"
07630cea 27#include "virt.h"
813e3a6f
PF
28
29static struct ether_addr mac_addr = {
30 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
31};
32
2ea8857e
PF
33static sd_event_source *hangcheck;
34static int test_dhcp_fd[2];
1a6c9136 35static int test_ifindex = 42;
5e256ea7
PF
36static int test_client_message_num;
37static be32_t test_iaid = 0;
38static uint8_t test_duid[14] = { };
2ea8857e 39
813e3a6f
PF
40static int test_client_basic(sd_event *e) {
41 sd_dhcp6_client *client;
7776f2ae 42 int v;
813e3a6f 43
9a254164 44 log_debug("/* %s */", __func__);
813e3a6f
PF
45
46 assert_se(sd_dhcp6_client_new(&client) >= 0);
47 assert_se(client);
48
49 assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
50
2f8e7633
LP
51 assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
52 assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL);
7fa69c0a 53 assert_se(sd_dhcp6_client_set_ifindex(client, -1) == -EINVAL);
2f8e7633 54 assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
813e3a6f 55
76253e73
DW
56 assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
57 sizeof (mac_addr),
58 ARPHRD_ETHER) >= 0);
813e3a6f 59
8006aa32
SA
60 assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1);
61 assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1);
62 assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1);
63 assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
64 assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
65
28a06068 66 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == 0);
2c1ab8ca
BG
67 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
68 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST);
69 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST);
70 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
28a06068 71 assert_se(sd_dhcp6_client_set_request_option(client, 10) == 0);
da6fe470 72
7776f2ae
PF
73 assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
74 v = 0;
75 assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
76 assert_se(v);
77 assert_se(sd_dhcp6_client_set_information_request(client, 0) >= 0);
78 v = 42;
79 assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
80 assert_se(v == 0);
81
82 v = 0;
83 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
84 assert_se(v);
85 v = 0;
86 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
87 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
88 assert_se(v);
89 v = 42;
90 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
91 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
92 assert_se(v);
93
94 assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
95 assert_se(sd_dhcp6_client_set_prefix_delegation(client, 1) >= 0);
96 v = 0;
97 assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
98 assert_se(v);
99 v = 0;
100 assert_se(sd_dhcp6_client_get_prefix_delegation(client, &v) >= 0);
101 assert_se(v);
102
813e3a6f
PF
103 assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
104
105 assert_se(sd_dhcp6_client_detach_event(client) >= 0);
106 assert_se(!sd_dhcp6_client_unref(client));
107
108 return 0;
109}
110
c43eea9f
BG
111static int test_parse_domain(sd_event *e) {
112 uint8_t *data;
113 char *domain;
114 char **list;
115 int r;
116
117 log_debug("/* %s */", __func__);
118
119 data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0 };
120 r = dhcp6_option_parse_domainname(data, 13, &domain);
121 assert_se(r == 0);
122 assert_se(domain);
123 assert_se(streq(domain, "example.com"));
124 free(domain);
125
126 data = (uint8_t []) { 4, 't', 'e', 's', 't' };
127 r = dhcp6_option_parse_domainname(data, 5, &domain);
128 assert_se(r == 0);
129 assert_se(domain);
130 assert_se(streq(domain, "test"));
131 free(domain);
132
133 data = (uint8_t []) { 0 };
134 r = dhcp6_option_parse_domainname(data, 1, &domain);
135 assert_se(r < 0);
136
137 data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0,
138 6, 'f', 'o', 'o', 'b', 'a', 'r', 0 };
139 r = dhcp6_option_parse_domainname_list(data, 21, &list);
140 assert_se(r == 2);
141 assert_se(list);
142 assert_se(streq(list[0], "example.com"));
143 assert_se(streq(list[1], "foobar"));
144 strv_free(list);
145
146 data = (uint8_t []) { 1, 'a', 0, 20, 'b', 'c' };
147 r = dhcp6_option_parse_domainname_list(data, 6, &list);
148 assert_se(r < 0);
149
150 data = (uint8_t []) { 0 , 0 };
151 r = dhcp6_option_parse_domainname_list(data, 2, &list);
152 assert_se(r < 0);
153
154 return 0;
155}
156
f12ed3bf
PF
157static int test_option(sd_event *e) {
158 uint8_t packet[] = {
159 'F', 'O', 'O',
2c1ab8ca 160 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x07,
f12ed3bf 161 'A', 'B', 'C', 'D', 'E', 'F', 'G',
2c1ab8ca 162 0x00, SD_DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
f12ed3bf
PF
163 '1', '2', '3', '4', '5', '6', '7', '8', '9',
164 'B', 'A', 'R',
165 };
166 uint8_t result[] = {
167 'F', 'O', 'O',
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 'B', 'A', 'R',
172 };
173 uint16_t optcode;
174 size_t optlen;
175 uint8_t *optval, *buf, *out;
176 size_t zero = 0, pos = 3;
177 size_t buflen = sizeof(packet), outlen = sizeof(result);
178
9a254164 179 log_debug("/* %s */", __func__);
f12ed3bf
PF
180
181 assert_se(buflen == outlen);
182
183 assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
184 &optval) == -ENOMSG);
185
186 buflen -= 3;
187 buf = &packet[3];
188 outlen -= 3;
189 out = &result[3];
190
191 assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
192 &optval) >= 0);
193 pos += 4 + optlen;
194 assert_se(buf == &packet[pos]);
2c1ab8ca 195 assert_se(optcode == SD_DHCP6_OPTION_ORO);
f12ed3bf
PF
196 assert_se(optlen == 7);
197 assert_se(buflen + pos == sizeof(packet));
198
199 assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
200 optval) >= 0);
201 assert_se(out == &result[pos]);
202 assert_se(*out == 0x00);
203
204 assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
205 &optval) >= 0);
206 pos += 4 + optlen;
207 assert_se(buf == &packet[pos]);
2c1ab8ca 208 assert_se(optcode == SD_DHCP6_OPTION_VENDOR_CLASS);
f12ed3bf
PF
209 assert_se(optlen == 9);
210 assert_se(buflen + pos == sizeof(packet));
211
212 assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
213 optval) >= 0);
214 assert_se(out == &result[pos]);
215 assert_se(*out == 'B');
216
217 assert_se(memcmp(packet, result, sizeof(packet)) == 0);
218
219 return 0;
220}
221
df296124
PF
222static int test_option_status(sd_event *e) {
223 uint8_t option1[] = {
224 /* IA NA */
225 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d,
226 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
227 /* status option */
228 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
229 };
230 static const uint8_t option2[] = {
231 /* IA NA */
232 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d,
233 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
234 /* IA Addr */
235 0x00, 0x05, 0x00, 0x1e,
236 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
237 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
238 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
239 /* status option */
240 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
241 };
242 static const uint8_t option3[] = {
243 /* IA NA */
244 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d,
245 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
246 /* IA Addr */
247 0x00, 0x05, 0x00, 0x24,
248 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
249 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
250 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
251 /* status option */
252 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 'f', 'o',
253 'o', 'b', 'a', 'r',
254 };
819c56f6
PF
255 static const uint8_t option4[] = {
256 /* IA PD */
257 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d,
258 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
259 /* IA PD Prefix */
260 0x00, 0x1a, 0x00, 0x1f,
261 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
262 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
263 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00,
265 /* status option */
266 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
267 };
268 static const uint8_t option5[] = {
269 /* IA PD */
270 0x00, 0x19, 0x00, 0x52, 0x1a, 0x1d, 0x1a, 0x1d,
271 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
272 /* IA PD Prefix #1 */
273 0x00, 0x1a, 0x00, 0x1f,
274 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
275 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
276 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00,
278 /* status option */
279 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
280 /* IA PD Prefix #2 */
281 0x00, 0x1a, 0x00, 0x1f,
282 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
283 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x0l, 0xd0,
284 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00,
286 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
287 };
df296124 288 DHCP6Option *option;
819c56f6 289 DHCP6IA ia, pd;
df296124
PF
290 int r = 0;
291
9a254164 292 log_debug("/* %s */", __func__);
df296124
PF
293
294 zero(ia);
295 option = (DHCP6Option *)option1;
296 assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
297
5c95a913
SS
298 r = dhcp6_option_parse_ia(option, &ia, NULL);
299 assert_se(r == 0);
df296124
PF
300 assert_se(ia.addresses == NULL);
301
302 option->len = htobe16(17);
5c95a913 303 r = dhcp6_option_parse_ia(option, &ia, NULL);
df296124
PF
304 assert_se(r == -ENOBUFS);
305 assert_se(ia.addresses == NULL);
306
307 option->len = htobe16(sizeof(DHCP6Option));
5c95a913 308 r = dhcp6_option_parse_ia(option, &ia, NULL);
df296124
PF
309 assert_se(r == -ENOBUFS);
310 assert_se(ia.addresses == NULL);
311
312 zero(ia);
313 option = (DHCP6Option *)option2;
314 assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
315
5c95a913 316 r = dhcp6_option_parse_ia(option, &ia, NULL);
df296124
PF
317 assert_se(r >= 0);
318 assert_se(ia.addresses == NULL);
319
320 zero(ia);
321 option = (DHCP6Option *)option3;
322 assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
323
5c95a913 324 r = dhcp6_option_parse_ia(option, &ia, NULL);
df296124
PF
325 assert_se(r >= 0);
326 assert_se(ia.addresses != NULL);
5a45fde5 327 dhcp6_lease_free_ia(&ia);
df296124 328
819c56f6
PF
329 zero(pd);
330 option = (DHCP6Option *)option4;
331 assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
332
5c95a913
SS
333 r = dhcp6_option_parse_ia(option, &pd, NULL);
334 assert_se(r >= 0);
819c56f6
PF
335 assert_se(pd.addresses != NULL);
336 assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
337 assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0);
338 assert_se(memcmp(&pd.ia_pd.lifetime_t2, &option4[12], 4) == 0);
5a45fde5 339 dhcp6_lease_free_ia(&pd);
819c56f6
PF
340
341 zero(pd);
342 option = (DHCP6Option *)option5;
343 assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
344
5c95a913
SS
345 r = dhcp6_option_parse_ia(option, &pd, NULL);
346 assert_se(r >= 0);
819c56f6 347 assert_se(pd.addresses != NULL);
5a45fde5 348 dhcp6_lease_free_ia(&pd);
819c56f6 349
df296124
PF
350 return 0;
351}
352
859cca44
PF
353static uint8_t msg_advertise[198] = {
354 0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
355 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
356 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
357 0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
358 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
359 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
360 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
361 0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
362 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
363 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
364 0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
365 0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
366 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
367 0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
368 0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
369 0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
370 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
372 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
373 0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
374 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
376 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
377 0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
378 0x53, 0x00, 0x07, 0x00, 0x01, 0x00
379};
380
c43eea9f 381static uint8_t msg_reply[191] = {
947527f8
PF
382 0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
383 0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
384 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
385 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
386 0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
387 0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
388 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
389 0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
390 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
391 0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
392 0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
393 0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
394 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
395 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
396 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
397 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
398 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
400 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
401 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
402 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
c43eea9f
BG
403 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00,
404 0x0e, 0x01, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e,
405 0x74, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61
947527f8
PF
406};
407
8006aa32
SA
408static uint8_t fqdn_wire[16] = {
409 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b',
410 0x05, 'i', 'n', 't', 'r', 'a', 0x00
411};
412
859cca44 413static int test_advertise_option(sd_event *e) {
4afd3348 414 _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
859cca44 415 DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
3bc424a3 416 size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0;
859cca44 417 uint32_t lt_pref, lt_valid;
859cca44 418 bool opt_clientid = false;
00813316 419 const struct in6_addr *addrs;
5c95a913
SS
420 uint8_t preference = 255;
421 struct in6_addr addr;
bc152ff8 422 char **domains;
5c95a913
SS
423 uint8_t *opt;
424 int r;
425 be32_t val;
859cca44 426
9a254164 427 log_debug("/* %s */", __func__);
859cca44 428
3bc424a3
PF
429 assert_se(len >= sizeof(DHCP6Message));
430
859cca44
PF
431 assert_se(dhcp6_lease_new(&lease) >= 0);
432
433 assert_se(advertise->type == DHCP6_ADVERTISE);
434 assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
435 0x0fb4e5);
436
3bc424a3
PF
437 while (pos < len) {
438 DHCP6Option *option = (DHCP6Option *)&advertise->options[pos];
439 const uint16_t optcode = be16toh(option->code);
440 const uint16_t optlen = be16toh(option->len);
441 uint8_t *optval = option->data;
859cca44
PF
442
443 switch(optcode) {
2c1ab8ca 444 case SD_DHCP6_OPTION_CLIENTID:
859cca44
PF
445 assert_se(optlen == 14);
446
447 opt_clientid = true;
448 break;
449
2c1ab8ca 450 case SD_DHCP6_OPTION_IA_NA:
859cca44
PF
451 assert_se(optlen == 94);
452 assert_se(!memcmp(optval, &msg_advertise[26], optlen));
453
454 val = htobe32(0x0ecfa37d);
455 assert_se(!memcmp(optval, &val, sizeof(val)));
456
457 val = htobe32(80);
458 assert_se(!memcmp(optval + 4, &val, sizeof(val)));
459
460 val = htobe32(120);
461 assert_se(!memcmp(optval + 8, &val, sizeof(val)));
462
5c95a913 463 assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
859cca44
PF
464
465 break;
466
2c1ab8ca 467 case SD_DHCP6_OPTION_SERVERID:
859cca44
PF
468 assert_se(optlen == 14);
469 assert_se(!memcmp(optval, &msg_advertise[179], optlen));
470
471 assert_se(dhcp6_lease_set_serverid(lease, optval,
472 optlen) >= 0);
473 break;
474
2c1ab8ca 475 case SD_DHCP6_OPTION_PREFERENCE:
859cca44
PF
476 assert_se(optlen == 1);
477 assert_se(!*optval);
478
479 assert_se(dhcp6_lease_set_preference(lease,
480 *optval) >= 0);
481 break;
482
2c1ab8ca 483 case SD_DHCP6_OPTION_ELAPSED_TIME:
d63be95a
PF
484 assert_se(optlen == 2);
485
486 break;
487
2c1ab8ca 488 case SD_DHCP6_OPTION_DNS_SERVERS:
bc152ff8
PF
489 assert_se(optlen == 16);
490 assert_se(dhcp6_lease_set_dns(lease, optval,
491 optlen) >= 0);
492 break;
493
2c1ab8ca 494 case SD_DHCP6_OPTION_DOMAIN_LIST:
bc152ff8
PF
495 assert_se(optlen == 11);
496 assert_se(dhcp6_lease_set_domains(lease, optval,
497 optlen) >= 0);
498 break;
499
2c1ab8ca 500 case SD_DHCP6_OPTION_SNTP_SERVERS:
bc152ff8
PF
501 assert_se(optlen == 16);
502 assert_se(dhcp6_lease_set_sntp(lease, optval,
503 optlen) >= 0);
504 break;
505
859cca44
PF
506 default:
507 break;
508 }
859cca44 509
3bc424a3
PF
510 pos += sizeof(*option) + optlen;
511 }
859cca44 512
3bc424a3 513 assert_se(pos == len);
859cca44
PF
514 assert_se(opt_clientid);
515
e7504d95
PF
516 sd_dhcp6_lease_reset_address_iter(lease);
517 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
518 &lt_valid) >= 0);
859cca44
PF
519 assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
520 assert_se(lt_pref == 150);
521 assert_se(lt_valid == 180);
e7504d95
PF
522 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
523 &lt_valid) == -ENOMSG);
859cca44 524
e7504d95
PF
525 sd_dhcp6_lease_reset_address_iter(lease);
526 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
527 &lt_valid) >= 0);
859cca44 528 assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
e7504d95
PF
529 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
530 &lt_valid) == -ENOMSG);
531 sd_dhcp6_lease_reset_address_iter(lease);
532 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
533 &lt_valid) >= 0);
859cca44 534 assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
e7504d95
PF
535 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
536 &lt_valid) == -ENOMSG);
859cca44
PF
537
538 assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
539 assert_se(len == 14);
540 assert_se(!memcmp(opt, &msg_advertise[179], len));
541
542 assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
543 assert_se(preference == 0);
544
bc152ff8
PF
545 r = sd_dhcp6_lease_get_dns(lease, &addrs);
546 assert_se(r == 1);
547 assert_se(!memcmp(addrs, &msg_advertise[124], r * 16));
548
549 r = sd_dhcp6_lease_get_domains(lease, &domains);
550 assert_se(r == 1);
551 assert_se(!strcmp("lab.intra", domains[0]));
552 assert_se(domains[1] == NULL);
553
554 r = sd_dhcp6_lease_get_ntp_addrs(lease, &addrs);
555 assert_se(r == 1);
556 assert_se(!memcmp(addrs, &msg_advertise[159], r * 16));
557
859cca44
PF
558 return 0;
559}
560
2ea8857e
PF
561static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
562 assert_not_reached("Test case should have completed in 2 seconds");
563
564 return 0;
565}
566
c4e8cedd
PF
567static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
568 void *userdata) {
569 sd_event *e = userdata;
bc152ff8 570 sd_dhcp6_lease *lease;
00813316 571 const struct in6_addr *addrs;
bc152ff8 572 char **domains;
2ea8857e 573
9a254164
YW
574 log_debug("/* %s */", __func__);
575
c4e8cedd 576 assert_se(e);
10c9ce61 577 assert_se(event == SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE);
2ea8857e 578
bc152ff8
PF
579 assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
580
581 assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
582 assert_se(!strcmp("lab.intra", domains[0]));
583 assert_se(domains[1] == NULL);
584
585 assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
586 assert_se(!memcmp(addrs, &msg_advertise[124], 16));
587
588 assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
589 assert_se(!memcmp(addrs, &msg_advertise[159], 16));
590
2c1ab8ca 591 assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
c4e8cedd 592
c4e8cedd 593 sd_event_exit(e, 0);
2ea8857e
PF
594}
595
5e256ea7 596static int test_client_send_reply(DHCP6Message *request) {
947527f8
PF
597 DHCP6Message reply;
598
599 reply.transaction_id = request->transaction_id;
600 reply.type = DHCP6_REPLY;
601
602 memcpy(msg_reply, &reply.transaction_id, 4);
603
604 memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
605
606 memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
607
608 assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
609 == sizeof(msg_reply));
610
5e256ea7
PF
611 return 0;
612}
613
3bc424a3 614static int test_client_verify_request(DHCP6Message *request, size_t len) {
4afd3348 615 _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
d63be95a 616 bool found_clientid = false, found_iana = false, found_serverid = false,
8006aa32 617 found_elapsed_time = false, found_fqdn = false;
5c95a913 618 uint32_t lt_pref, lt_valid;
5e256ea7 619 struct in6_addr addr;
5c95a913 620 size_t pos = 0;
5e256ea7 621 be32_t val;
5e256ea7 622
9a254164 623 log_debug("/* %s */", __func__);
5e256ea7 624
9a254164 625 assert_se(request->type == DHCP6_REQUEST);
5e256ea7
PF
626 assert_se(dhcp6_lease_new(&lease) >= 0);
627
3bc424a3
PF
628 len -= sizeof(DHCP6Message);
629
630 while (pos < len) {
631 DHCP6Option *option = (DHCP6Option *)&request->options[pos];
632 uint16_t optcode = be16toh(option->code);
633 uint16_t optlen = be16toh(option->len);
634 uint8_t *optval = option->data;
635
5e256ea7 636 switch(optcode) {
2c1ab8ca 637 case SD_DHCP6_OPTION_CLIENTID:
5e256ea7
PF
638 assert_se(!found_clientid);
639 found_clientid = true;
640
641 assert_se(!memcmp(optval, &test_duid,
642 sizeof(test_duid)));
643
644 break;
645
2c1ab8ca 646 case SD_DHCP6_OPTION_IA_NA:
5e256ea7
PF
647 assert_se(!found_iana);
648 found_iana = true;
649
5e256ea7
PF
650 assert_se(optlen == 40);
651 assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
652
653 val = htobe32(80);
654 assert_se(!memcmp(optval + 4, &val, sizeof(val)));
655
656 val = htobe32(120);
657 assert_se(!memcmp(optval + 8, &val, sizeof(val)));
658
5c95a913 659 assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
5e256ea7
PF
660
661 break;
662
2c1ab8ca 663 case SD_DHCP6_OPTION_SERVERID:
5e256ea7
PF
664 assert_se(!found_serverid);
665 found_serverid = true;
666
667 assert_se(optlen == 14);
668 assert_se(!memcmp(&msg_advertise[179], optval, optlen));
669
d63be95a
PF
670 break;
671
2c1ab8ca 672 case SD_DHCP6_OPTION_ELAPSED_TIME:
d63be95a
PF
673 assert_se(!found_elapsed_time);
674 found_elapsed_time = true;
675
676 assert_se(optlen == 2);
677
8006aa32
SA
678 break;
679 case SD_DHCP6_OPTION_FQDN:
680 assert_se(!found_fqdn);
681 found_fqdn = true;
682
683 assert_se(optlen == 17);
684
685 assert_se(optval[0] == 0x01);
686 assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
5e256ea7
PF
687 break;
688 }
3bc424a3
PF
689
690 pos += sizeof(*option) + optlen;
5e256ea7
PF
691 }
692
d63be95a
PF
693 assert_se(found_clientid && found_iana && found_serverid &&
694 found_elapsed_time);
5e256ea7 695
e7504d95
PF
696 sd_dhcp6_lease_reset_address_iter(lease);
697 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
698 &lt_valid) >= 0);
5e256ea7
PF
699 assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
700 assert_se(lt_pref == 150);
701 assert_se(lt_valid == 180);
702
e7504d95
PF
703 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
704 &lt_valid) == -ENOMSG);
5e256ea7 705
5e256ea7
PF
706 return 0;
707}
708
52efd56a 709static int test_client_send_advertise(DHCP6Message *solicit) {
5e256ea7
PF
710 DHCP6Message advertise;
711
712 advertise.transaction_id = solicit->transaction_id;
713 advertise.type = DHCP6_ADVERTISE;
714
715 memcpy(msg_advertise, &advertise.transaction_id, 4);
716
717 memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
718
719 memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
720
721 assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
722 == sizeof(msg_advertise));
723
724 return 0;
725}
726
3bc424a3 727static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) {
d63be95a 728 bool found_clientid = false, found_iana = false,
8006aa32 729 found_elapsed_time = false, found_fqdn = false;
3bc424a3 730 size_t pos = 0;
2ea8857e 731
9a254164
YW
732 log_debug("/* %s */", __func__);
733
2ea8857e
PF
734 assert_se(solicit->type == DHCP6_SOLICIT);
735
3bc424a3
PF
736 len -= sizeof(DHCP6Message);
737
738 while (pos < len) {
739 DHCP6Option *option = (DHCP6Option *)&solicit->options[pos];
740 uint16_t optcode = be16toh(option->code);
741 uint16_t optlen = be16toh(option->len);
742 uint8_t *optval = option->data;
743
2ea8857e 744 switch(optcode) {
2c1ab8ca 745 case SD_DHCP6_OPTION_CLIENTID:
2ea8857e
PF
746 assert_se(!found_clientid);
747 found_clientid = true;
748
5e256ea7
PF
749 assert_se(optlen == sizeof(test_duid));
750 memcpy(&test_duid, optval, sizeof(test_duid));
2ea8857e
PF
751
752 break;
753
2c1ab8ca 754 case SD_DHCP6_OPTION_IA_NA:
2ea8857e
PF
755 assert_se(!found_iana);
756 found_iana = true;
757
758 assert_se(optlen == 12);
759
5e256ea7
PF
760 memcpy(&test_iaid, optval, sizeof(test_iaid));
761
d63be95a
PF
762 break;
763
2c1ab8ca 764 case SD_DHCP6_OPTION_ELAPSED_TIME:
d63be95a
PF
765 assert_se(!found_elapsed_time);
766 found_elapsed_time = true;
767
768 assert_se(optlen == 2);
769
8006aa32
SA
770 break;
771
772 case SD_DHCP6_OPTION_FQDN:
773 assert_se(!found_fqdn);
774 found_fqdn = true;
775
776 assert_se(optlen == 17);
777
778 assert_se(optval[0] == 0x01);
779 assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
780
2ea8857e
PF
781 break;
782 }
3bc424a3
PF
783
784 pos += sizeof(*option) + optlen;
2ea8857e
PF
785 }
786
3bc424a3 787 assert_se(pos == len);
d63be95a 788 assert_se(found_clientid && found_iana && found_elapsed_time);
2ea8857e 789
2ea8857e
PF
790 return 0;
791}
792
c4e8cedd
PF
793static void test_client_information_cb(sd_dhcp6_client *client, int event,
794 void *userdata) {
795 sd_event *e = userdata;
bc152ff8 796 sd_dhcp6_lease *lease;
00813316 797 const struct in6_addr *addrs;
c601ebf7 798 struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
bc152ff8 799 char **domains;
c43eea9f 800 const char *fqdn;
c4e8cedd 801
9a254164
YW
802 log_debug("/* %s */", __func__);
803
c4e8cedd 804 assert_se(e);
10c9ce61 805 assert_se(event == SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST);
c4e8cedd 806
bc152ff8
PF
807 assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
808
809 assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
810 assert_se(!strcmp("lab.intra", domains[0]));
811 assert_se(domains[1] == NULL);
812
c43eea9f
BG
813 assert_se(sd_dhcp6_lease_get_fqdn(lease, &fqdn) >= 0);
814 assert_se(streq(fqdn, "client.intra"));
815
bc152ff8
PF
816 assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
817 assert_se(!memcmp(addrs, &msg_advertise[124], 16));
818
819 assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
820 assert_se(!memcmp(addrs, &msg_advertise[159], 16));
821
44598572
PF
822 assert_se(sd_dhcp6_client_set_information_request(client, false) == -EBUSY);
823 assert_se(sd_dhcp6_client_set_callback(client, NULL, e) >= 0);
824 assert_se(sd_dhcp6_client_stop(client) >= 0);
c4e8cedd 825 assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
44598572 826
c4e8cedd
PF
827 assert_se(sd_dhcp6_client_set_callback(client,
828 test_client_solicit_cb, e) >= 0);
829
c601ebf7
TG
830 assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
831
c4e8cedd 832 assert_se(sd_dhcp6_client_start(client) >= 0);
3bc424a3 833
c4e8cedd
PF
834}
835
836static int test_client_verify_information_request(DHCP6Message *information_request,
3bc424a3 837 size_t len) {
c4e8cedd 838
4afd3348 839 _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
3bc424a3 840 size_t pos = 0;
c4e8cedd 841 bool found_clientid = false, found_elapsed_time = false;
c4e8cedd
PF
842 struct in6_addr addr;
843 uint32_t lt_pref, lt_valid;
844
9a254164 845 log_debug("/* %s */", __func__);
c4e8cedd 846
9a254164 847 assert_se(information_request->type == DHCP6_INFORMATION_REQUEST);
c4e8cedd
PF
848 assert_se(dhcp6_lease_new(&lease) >= 0);
849
3bc424a3
PF
850 len -= sizeof(DHCP6Message);
851
852 while (pos < len) {
853 DHCP6Option *option = (DHCP6Option *)&information_request->options[pos];
854 uint16_t optcode = be16toh(option->code);
855 uint16_t optlen = be16toh(option->len);
856 uint8_t *optval = option->data;
857
c4e8cedd 858 switch(optcode) {
2c1ab8ca 859 case SD_DHCP6_OPTION_CLIENTID:
c4e8cedd
PF
860 assert_se(!found_clientid);
861 found_clientid = true;
862
863 assert_se(optlen == sizeof(test_duid));
864 memcpy(&test_duid, optval, sizeof(test_duid));
865
866 break;
867
2c1ab8ca 868 case SD_DHCP6_OPTION_IA_NA:
c4e8cedd
PF
869 assert_not_reached("IA TA option must not be present");
870
871 break;
872
2c1ab8ca 873 case SD_DHCP6_OPTION_SERVERID:
c4e8cedd
PF
874 assert_not_reached("Server ID option must not be present");
875
876 break;
877
2c1ab8ca 878 case SD_DHCP6_OPTION_ELAPSED_TIME:
c4e8cedd
PF
879 assert_se(!found_elapsed_time);
880 found_elapsed_time = true;
881
882 assert_se(optlen == 2);
883
884 break;
885 }
3bc424a3
PF
886
887 pos += sizeof(*option) + optlen;
c4e8cedd
PF
888 }
889
3bc424a3 890 assert_se(pos == len);
c4e8cedd
PF
891 assert_se(found_clientid && found_elapsed_time);
892
e7504d95 893 sd_dhcp6_lease_reset_address_iter(lease);
c4e8cedd 894
e7504d95
PF
895 assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
896 &lt_valid) == -ENOMSG);
c4e8cedd
PF
897
898 return 0;
899}
900
2ea8857e
PF
901int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
902 const void *packet, size_t len) {
903 struct in6_addr mcast =
904 IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
905 DHCP6Message *message;
2ea8857e
PF
906
907 assert_se(s == test_dhcp_fd[0]);
908 assert_se(server_address);
909 assert_se(packet);
910 assert_se(len > sizeof(DHCP6Message) + 4);
2ea8857e
PF
911 assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
912
913 message = (DHCP6Message *)packet;
2ea8857e
PF
914
915 assert_se(message->transaction_id & 0x00ffffff);
916
5e256ea7 917 if (test_client_message_num == 0) {
3bc424a3 918 test_client_verify_information_request(message, len);
c4e8cedd
PF
919 test_client_send_reply(message);
920 test_client_message_num++;
921 } else if (test_client_message_num == 1) {
3bc424a3 922 test_client_verify_solicit(message, len);
5e256ea7
PF
923 test_client_send_advertise(message);
924 test_client_message_num++;
c4e8cedd 925 } else if (test_client_message_num == 2) {
3bc424a3 926 test_client_verify_request(message, len);
5e256ea7
PF
927 test_client_send_reply(message);
928 test_client_message_num++;
929 }
2ea8857e
PF
930
931 return len;
932}
933
1a6c9136
YW
934int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) {
935 assert_se(ifindex == test_ifindex);
da6fe470 936
3e29b889 937 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) < 0)
c4e8cedd 938 return -errno;
2ea8857e 939
c4e8cedd 940 return test_dhcp_fd[0];
2ea8857e
PF
941}
942
943static int test_client_solicit(sd_event *e) {
944 sd_dhcp6_client *client;
c601ebf7 945 struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
7776f2ae 946 int val;
2ea8857e 947
9a254164 948 log_debug("/* %s */", __func__);
2ea8857e
PF
949
950 assert_se(sd_dhcp6_client_new(&client) >= 0);
951 assert_se(client);
952
953 assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
954
1a6c9136 955 assert_se(sd_dhcp6_client_set_ifindex(client, test_ifindex) == 0);
76253e73
DW
956 assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
957 sizeof (mac_addr),
958 ARPHRD_ETHER) >= 0);
8006aa32 959 assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);
2ea8857e 960
c4e8cedd 961 assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
7776f2ae
PF
962 assert_se(val == 0);
963 assert_se(sd_dhcp6_client_set_information_request(client, 42) >= 0);
c4e8cedd 964 assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
7776f2ae 965 assert_se(val);
c4e8cedd 966
2ea8857e 967 assert_se(sd_dhcp6_client_set_callback(client,
c4e8cedd 968 test_client_information_cb, e) >= 0);
2ea8857e 969
39cf0351
LP
970 assert_se(sd_event_add_time_relative(e, &hangcheck, clock_boottime_or_monotonic(),
971 2 * USEC_PER_SEC, 0,
972 test_hangcheck, NULL) >= 0);
2ea8857e 973
c601ebf7
TG
974 assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
975
2ea8857e
PF
976 assert_se(sd_dhcp6_client_start(client) >= 0);
977
978 sd_event_loop(e);
979
980 hangcheck = sd_event_source_unref(hangcheck);
981
982 assert_se(!sd_dhcp6_client_unref(client));
983
984 test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
985
986 return 0;
987}
988
813e3a6f 989int main(int argc, char *argv[]) {
4afd3348 990 _cleanup_(sd_event_unrefp) sd_event *e;
813e3a6f
PF
991
992 assert_se(sd_event_new(&e) >= 0);
993
6d7c4033 994 test_setup_logging(LOG_DEBUG);
813e3a6f
PF
995
996 test_client_basic(e);
f12ed3bf 997 test_option(e);
df296124 998 test_option_status(e);
859cca44 999 test_advertise_option(e);
2ea8857e 1000 test_client_solicit(e);
c43eea9f 1001 test_parse_domain(e);
f12ed3bf 1002
813e3a6f
PF
1003 return 0;
1004}