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>
12 #if HAVE_VALGRIND_VALGRIND_H
13 # include <valgrind/valgrind.h>
16 #include "sd-dhcp-client.h"
19 #include "alloc-util.h"
20 #include "dhcp-identifier.h"
21 #include "dhcp-network.h"
22 #include "dhcp-option.h"
23 #include "dhcp-packet.h"
24 #include "ether-addr-util.h"
26 #include "random-util.h"
29 static struct hw_addr_data hw_addr
= {
31 .ether
= {{ 'A', 'B', 'C', '1', '2', '3' }},
34 .ether
= {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }},
36 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
38 static bool verbose
= true;
39 static int test_fd
[2];
40 static test_callback_recv_t callback_recv
;
43 static void test_request_basic(sd_event
*e
) {
46 sd_dhcp_client
*client
;
49 printf("* %s\n", __func__
);
51 /* Initialize client without Anonymize settings. */
52 r
= sd_dhcp_client_new(&client
, false);
57 r
= sd_dhcp_client_attach_event(client
, e
, 0);
60 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
61 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
62 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
64 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
65 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
66 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
67 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
68 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
70 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
71 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
72 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
73 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
74 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
76 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_SUBNET_MASK
) == 0);
77 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_ROUTER
) == 0);
78 /* This PRL option is not set when using Anonymize, but in this test
79 * Anonymize settings are not being used. */
80 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 0);
81 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME
) == 0);
82 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == 0);
84 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PAD
) == -EINVAL
);
85 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_END
) == -EINVAL
);
86 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
87 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
88 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
90 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
91 * default PRL when using Anonymize, so it is changed to other option
92 * that is not set by default, to check that it was set successfully.
93 * Options not set by default (using or not anonymize) are option 17
94 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
95 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 1);
96 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
97 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 1);
98 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
100 sd_dhcp_client_unref(client
);
103 static void test_request_anonymize(sd_event
*e
) {
106 sd_dhcp_client
*client
;
109 printf("* %s\n", __func__
);
111 /* Initialize client with Anonymize settings. */
112 r
= sd_dhcp_client_new(&client
, true);
117 r
= sd_dhcp_client_attach_event(client
, e
, 0);
120 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_NETBIOS_NAME_SERVER
) == 0);
121 /* This PRL option is not set when using Anonymize */
122 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 1);
123 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
125 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
126 * default PRL when using Anonymize, */
127 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 1);
128 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
130 sd_dhcp_client_unref(client
);
133 static void test_checksum(void) {
135 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
136 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0xff, 0xff, 0xff, 0xff
141 printf("* %s\n", __func__
);
143 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
146 static void test_dhcp_identifier_set_iaid(void) {
147 uint32_t iaid_legacy
;
150 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid_legacy
) >= 0);
151 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ false, &iaid
) >= 0);
153 /* we expect, that the MAC address was hashed. The legacy value is in native
155 assert_se(iaid_legacy
== 0x8dde4ba8u
);
156 assert_se(iaid
== htole32(0x8dde4ba8u
));
157 #if __BYTE_ORDER == __LITTLE_ENDIAN
158 assert_se(iaid
== iaid_legacy
);
160 assert_se(iaid
== bswap_32(iaid_legacy
));
164 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
166 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
172 assert_se(dhcp_identifier_set_duid_en(&duid
, &duid_len
) >= 0);
173 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid
) >= 0);
175 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
176 assert_se(len
== 19);
177 assert_se(((uint8_t*) option
)[0] == 0xff);
179 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
180 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
191 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
193 _cleanup_free_ DHCPPacket
*discover
= NULL
;
194 uint16_t ip_check
, udp_check
;
199 size
= sizeof(DHCPPacket
);
200 assert_se(len
> size
);
202 discover
= memdup(packet
, len
);
204 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
205 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
206 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
207 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
208 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
209 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
211 ip_check
= discover
->ip
.check
;
213 discover
->ip
.ttl
= 0;
214 discover
->ip
.check
= discover
->udp
.len
;
216 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
217 assert_se(udp_check
== 0xffff);
219 discover
->ip
.ttl
= IPDEFTTL
;
220 discover
->ip
.check
= ip_check
;
222 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
223 assert_se(ip_check
== 0xffff);
225 assert_se(discover
->dhcp
.xid
);
226 assert_se(memcmp(discover
->dhcp
.chaddr
, hw_addr
.bytes
, hw_addr
.length
) == 0);
228 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
230 assert_se(callback_recv
);
231 callback_recv(size
, &discover
->dhcp
);
236 int dhcp_network_bind_raw_socket(
238 union sockaddr_union
*link
,
240 const struct hw_addr_data
*_hw_addr
,
241 const struct hw_addr_data
*_bcast_addr
,
244 bool so_priority_set
,
247 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
253 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
256 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
263 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
267 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
270 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
271 assert_se(res
== DHCP_DISCOVER
);
274 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
279 static void test_discover_message(sd_event
*e
) {
280 sd_dhcp_client
*client
;
284 printf("* %s\n", __func__
);
286 r
= sd_dhcp_client_new(&client
, false);
290 r
= sd_dhcp_client_attach_event(client
, e
, 0);
293 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
294 assert_se(sd_dhcp_client_set_mac(client
, hw_addr
.bytes
, bcast_addr
.bytes
, hw_addr
.length
, ARPHRD_ETHER
) >= 0);
296 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
298 callback_recv
= test_discover_message_verify
;
300 res
= sd_dhcp_client_start(client
);
302 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
304 sd_event_run(e
, UINT64_MAX
);
306 sd_dhcp_client_stop(client
);
307 sd_dhcp_client_unref(client
);
309 test_fd
[1] = safe_close(test_fd
[1]);
311 callback_recv
= NULL
;
314 static uint8_t test_addr_acq_offer
[] = {
315 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
316 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
317 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
318 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
319 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
321 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
349 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
350 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
351 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
352 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
353 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
354 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 static uint8_t test_addr_acq_ack
[] = {
359 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
360 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
361 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
362 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
365 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
393 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
394 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
395 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
396 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
397 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
398 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 static int test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
404 sd_event
*e
= userdata
;
405 sd_dhcp_lease
*lease
;
407 const struct in_addr
*addrs
;
410 assert_se(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
412 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
415 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
416 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
417 sizeof(addr
.s_addr
)) == 0);
419 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
420 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
421 sizeof(addr
.s_addr
)) == 0);
423 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
424 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
425 sizeof(addrs
[0].s_addr
)) == 0);
428 printf(" DHCP address acquired\n");
435 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
436 uint16_t udp_check
= 0;
437 uint8_t *msg_bytes
= (uint8_t *)request
;
440 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
441 assert_se(res
== DHCP_REQUEST
);
442 assert_se(xid
== request
->xid
);
444 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
447 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
449 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
450 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
451 memcpy(&test_addr_acq_ack
[56], hw_addr
.bytes
, hw_addr
.length
);
453 callback_recv
= NULL
;
455 res
= write(test_fd
[1], test_addr_acq_ack
,
456 sizeof(test_addr_acq_ack
));
457 assert_se(res
== sizeof(test_addr_acq_ack
));
460 printf(" send DHCP Ack\n");
465 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
466 uint16_t udp_check
= 0;
467 uint8_t *msg_bytes
= (uint8_t *)discover
;
470 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
471 assert_se(res
== DHCP_DISCOVER
);
473 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
478 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
480 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
481 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
482 memcpy(&test_addr_acq_offer
[56], hw_addr
.bytes
, hw_addr
.length
);
484 callback_recv
= test_addr_acq_recv_request
;
486 res
= write(test_fd
[1], test_addr_acq_offer
,
487 sizeof(test_addr_acq_offer
));
488 assert_se(res
== sizeof(test_addr_acq_offer
));
491 printf(" sent DHCP Offer\n");
496 static void test_addr_acq(sd_event
*e
) {
497 sd_dhcp_client
*client
;
501 printf("* %s\n", __func__
);
503 r
= sd_dhcp_client_new(&client
, false);
507 r
= sd_dhcp_client_attach_event(client
, e
, 0);
510 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
511 assert_se(sd_dhcp_client_set_mac(client
, hw_addr
.bytes
, bcast_addr
.bytes
, hw_addr
.length
, ARPHRD_ETHER
) >= 0);
513 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
515 callback_recv
= test_addr_acq_recv_discover
;
517 assert_se(sd_event_add_time_relative(e
, NULL
, CLOCK_BOOTTIME
,
519 NULL
, INT_TO_PTR(-ETIMEDOUT
)) >= 0);
521 res
= sd_dhcp_client_start(client
);
522 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
524 assert_se(sd_event_loop(e
) >= 0);
526 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
527 assert_se(sd_dhcp_client_stop(client
) >= 0);
528 sd_dhcp_client_unref(client
);
530 test_fd
[1] = safe_close(test_fd
[1]);
532 callback_recv
= NULL
;
536 int main(int argc
, char *argv
[]) {
537 _cleanup_(sd_event_unrefp
) sd_event
*e
;
539 assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0);
541 test_setup_logging(LOG_DEBUG
);
543 assert_se(sd_event_new(&e
) >= 0);
545 test_request_basic(e
);
546 test_request_anonymize(e
);
548 test_dhcp_identifier_set_iaid();
550 test_discover_message(e
);
553 #if HAVE_VALGRIND_VALGRIND_H
554 /* Make sure the async_close thread has finished.
555 * valgrind would report some of the phread_* structures
556 * as not cleaned up properly. */
557 if (RUNNING_ON_VALGRIND
)