1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2013 Intel Corporation. All rights reserved.
8 #include <net/if_arp.h>
10 #include <sys/socket.h>
13 #include "sd-dhcp-client.h"
16 #include "alloc-util.h"
17 #include "dhcp-identifier.h"
18 #include "dhcp-internal.h"
19 #include "dhcp-protocol.h"
20 #include "ether-addr-util.h"
22 #include "random-util.h"
25 static struct hw_addr_data hw_addr
= {
27 .ether
= {{ 'A', 'B', 'C', '1', '2', '3' }},
30 .ether
= {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }},
32 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
34 static bool verbose
= true;
35 static int test_fd
[2];
36 static test_callback_recv_t callback_recv
;
39 static void test_request_basic(sd_event
*e
) {
42 sd_dhcp_client
*client
;
45 printf("* %s\n", __func__
);
47 /* Initialize client without Anonymize settings. */
48 r
= sd_dhcp_client_new(&client
, false);
53 r
= sd_dhcp_client_attach_event(client
, e
, 0);
56 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
57 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
58 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
60 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
61 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
62 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
63 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
64 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
66 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
67 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
68 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
69 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
70 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
72 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_SUBNET_MASK
) == 0);
73 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_ROUTER
) == 0);
74 /* This PRL option is not set when using Anonymize, but in this test
75 * Anonymize settings are not being used. */
76 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 0);
77 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME
) == 0);
78 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == 0);
80 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PAD
) == -EINVAL
);
81 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_END
) == -EINVAL
);
82 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
83 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
84 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
86 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
87 * default PRL when using Anonymize, so it is changed to other option
88 * that is not set by default, to check that it was set successfully.
89 * Options not set by default (using or not anonymize) are option 17
90 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
91 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 1);
92 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
93 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 1);
94 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
96 sd_dhcp_client_unref(client
);
99 static void test_request_anonymize(sd_event
*e
) {
102 sd_dhcp_client
*client
;
105 printf("* %s\n", __func__
);
107 /* Initialize client with Anonymize settings. */
108 r
= sd_dhcp_client_new(&client
, true);
113 r
= sd_dhcp_client_attach_event(client
, e
, 0);
116 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_NETBIOS_NAME_SERVER
) == 0);
117 /* This PRL option is not set when using Anonymize */
118 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 1);
119 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
121 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
122 * default PRL when using Anonymize, */
123 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 1);
124 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
126 sd_dhcp_client_unref(client
);
129 static void test_checksum(void) {
131 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
132 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0xff, 0xff, 0xff, 0xff
137 printf("* %s\n", __func__
);
139 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
142 static void test_dhcp_identifier_set_iaid(void) {
143 uint32_t iaid_legacy
;
146 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid_legacy
) >= 0);
147 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ false, &iaid
) >= 0);
149 /* we expect, that the MAC address was hashed. The legacy value is in native
151 assert_se(iaid_legacy
== 0x8dde4ba8u
);
152 assert_se(iaid
== htole32(0x8dde4ba8u
));
153 #if __BYTE_ORDER == __LITTLE_ENDIAN
154 assert_se(iaid
== iaid_legacy
);
156 assert_se(iaid
== bswap_32(iaid_legacy
));
160 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
162 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
168 assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid
, &duid_len
) >= 0);
169 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid
) >= 0);
171 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
172 assert_se(len
== 19);
173 assert_se(((uint8_t*) option
)[0] == 0xff);
175 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
176 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
187 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
189 _cleanup_free_ DHCPPacket
*discover
;
190 uint16_t ip_check
, udp_check
;
195 size
= sizeof(DHCPPacket
);
196 assert_se(len
> size
);
198 discover
= memdup(packet
, len
);
200 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
201 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
202 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
203 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
204 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
205 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
207 ip_check
= discover
->ip
.check
;
209 discover
->ip
.ttl
= 0;
210 discover
->ip
.check
= discover
->udp
.len
;
212 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
213 assert_se(udp_check
== 0xffff);
215 discover
->ip
.ttl
= IPDEFTTL
;
216 discover
->ip
.check
= ip_check
;
218 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
219 assert_se(ip_check
== 0xffff);
221 assert_se(discover
->dhcp
.xid
);
222 assert_se(memcmp(discover
->dhcp
.chaddr
, hw_addr
.bytes
, hw_addr
.length
) == 0);
224 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
226 assert_se(callback_recv
);
227 callback_recv(size
, &discover
->dhcp
);
232 int dhcp_network_bind_raw_socket(
234 union sockaddr_union
*link
,
236 const struct hw_addr_data
*_hw_addr
,
237 const struct hw_addr_data
*_bcast_addr
,
238 uint16_t arp_type
, uint16_t port
) {
240 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
246 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
249 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
256 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
260 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
263 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
264 assert_se(res
== DHCP_DISCOVER
);
267 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
272 static void test_discover_message(sd_event
*e
) {
273 sd_dhcp_client
*client
;
277 printf("* %s\n", __func__
);
279 r
= sd_dhcp_client_new(&client
, false);
283 r
= sd_dhcp_client_attach_event(client
, e
, 0);
286 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
287 assert_se(sd_dhcp_client_set_mac(client
, hw_addr
.bytes
, bcast_addr
.bytes
, hw_addr
.length
, ARPHRD_ETHER
) >= 0);
288 dhcp_client_set_test_mode(client
, true);
290 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
292 callback_recv
= test_discover_message_verify
;
294 res
= sd_dhcp_client_start(client
);
296 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
298 sd_event_run(e
, UINT64_MAX
);
300 sd_dhcp_client_stop(client
);
301 sd_dhcp_client_unref(client
);
303 test_fd
[1] = safe_close(test_fd
[1]);
305 callback_recv
= NULL
;
308 static uint8_t test_addr_acq_offer
[] = {
309 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
310 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
311 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
312 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
313 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
315 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
343 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
344 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
345 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
346 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
347 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
348 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 static uint8_t test_addr_acq_ack
[] = {
353 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
354 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
355 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
356 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
359 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
387 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
388 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
389 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
390 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
391 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
392 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 static int test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
398 sd_event
*e
= userdata
;
399 sd_dhcp_lease
*lease
;
401 const struct in_addr
*addrs
;
404 assert_se(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
406 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
409 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
410 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
411 sizeof(addr
.s_addr
)) == 0);
413 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
414 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
415 sizeof(addr
.s_addr
)) == 0);
417 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
418 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
419 sizeof(addrs
[0].s_addr
)) == 0);
422 printf(" DHCP address acquired\n");
429 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
430 uint16_t udp_check
= 0;
431 uint8_t *msg_bytes
= (uint8_t *)request
;
434 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
435 assert_se(res
== DHCP_REQUEST
);
436 assert_se(xid
== request
->xid
);
438 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
441 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
443 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
444 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
445 memcpy(&test_addr_acq_ack
[56], hw_addr
.bytes
, hw_addr
.length
);
447 callback_recv
= NULL
;
449 res
= write(test_fd
[1], test_addr_acq_ack
,
450 sizeof(test_addr_acq_ack
));
451 assert_se(res
== sizeof(test_addr_acq_ack
));
454 printf(" send DHCP Ack\n");
459 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
460 uint16_t udp_check
= 0;
461 uint8_t *msg_bytes
= (uint8_t *)discover
;
464 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
465 assert_se(res
== DHCP_DISCOVER
);
467 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
472 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
474 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
475 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
476 memcpy(&test_addr_acq_offer
[56], hw_addr
.bytes
, hw_addr
.length
);
478 callback_recv
= test_addr_acq_recv_request
;
480 res
= write(test_fd
[1], test_addr_acq_offer
,
481 sizeof(test_addr_acq_offer
));
482 assert_se(res
== sizeof(test_addr_acq_offer
));
485 printf(" sent DHCP Offer\n");
490 static void test_addr_acq(sd_event
*e
) {
491 sd_dhcp_client
*client
;
495 printf("* %s\n", __func__
);
497 r
= sd_dhcp_client_new(&client
, false);
501 r
= sd_dhcp_client_attach_event(client
, e
, 0);
504 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
505 assert_se(sd_dhcp_client_set_mac(client
, hw_addr
.bytes
, bcast_addr
.bytes
, hw_addr
.length
, ARPHRD_ETHER
) >= 0);
506 dhcp_client_set_test_mode(client
, true);
508 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
510 callback_recv
= test_addr_acq_recv_discover
;
512 assert_se(sd_event_add_time_relative(e
, NULL
, CLOCK_BOOTTIME
,
514 NULL
, INT_TO_PTR(-ETIMEDOUT
)) >= 0);
516 res
= sd_dhcp_client_start(client
);
517 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
519 assert_se(sd_event_loop(e
) >= 0);
521 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
522 assert_se(sd_dhcp_client_stop(client
) >= 0);
523 sd_dhcp_client_unref(client
);
525 test_fd
[1] = safe_close(test_fd
[1]);
527 callback_recv
= NULL
;
531 int main(int argc
, char *argv
[]) {
532 _cleanup_(sd_event_unrefp
) sd_event
*e
;
534 test_setup_logging(LOG_DEBUG
);
536 assert_se(sd_event_new(&e
) >= 0);
538 test_request_basic(e
);
539 test_request_anonymize(e
);
541 test_dhcp_identifier_set_iaid();
543 test_discover_message(e
);
547 /* Make sure the async_close thread has finished.
548 * valgrind would report some of the phread_* structures
549 * as not cleaned up properly. */