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-internal.h"
22 #include "dhcp-protocol.h"
23 #include "ether-addr-util.h"
25 #include "random-util.h"
28 static struct hw_addr_data hw_addr
= {
30 .ether
= {{ 'A', 'B', 'C', '1', '2', '3' }},
33 .ether
= {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }},
35 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
37 static bool verbose
= true;
38 static int test_fd
[2];
39 static test_callback_recv_t callback_recv
;
42 static void test_request_basic(sd_event
*e
) {
45 sd_dhcp_client
*client
;
48 printf("* %s\n", __func__
);
50 /* Initialize client without Anonymize settings. */
51 r
= sd_dhcp_client_new(&client
, false);
56 r
= sd_dhcp_client_attach_event(client
, e
, 0);
59 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
60 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
61 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
63 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
64 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
65 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
66 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
67 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
69 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
70 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
71 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
72 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
73 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
75 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_SUBNET_MASK
) == 0);
76 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_ROUTER
) == 0);
77 /* This PRL option is not set when using Anonymize, but in this test
78 * Anonymize settings are not being used. */
79 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 0);
80 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME
) == 0);
81 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == 0);
83 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PAD
) == -EINVAL
);
84 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_END
) == -EINVAL
);
85 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
86 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
87 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
89 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
90 * default PRL when using Anonymize, so it is changed to other option
91 * that is not set by default, to check that it was set successfully.
92 * Options not set by default (using or not anonymize) are option 17
93 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
94 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 1);
95 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
96 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 1);
97 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
99 sd_dhcp_client_unref(client
);
102 static void test_request_anonymize(sd_event
*e
) {
105 sd_dhcp_client
*client
;
108 printf("* %s\n", __func__
);
110 /* Initialize client with Anonymize settings. */
111 r
= sd_dhcp_client_new(&client
, true);
116 r
= sd_dhcp_client_attach_event(client
, e
, 0);
119 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_NETBIOS_NAME_SERVER
) == 0);
120 /* This PRL option is not set when using Anonymize */
121 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_HOST_NAME
) == 1);
122 assert_se(sd_dhcp_client_set_request_option(client
, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
) == -EINVAL
);
124 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
125 * default PRL when using Anonymize, */
126 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 1);
127 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
129 sd_dhcp_client_unref(client
);
132 static void test_checksum(void) {
134 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
135 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0xff, 0xff, 0xff, 0xff
140 printf("* %s\n", __func__
);
142 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
145 static void test_dhcp_identifier_set_iaid(void) {
146 uint32_t iaid_legacy
;
149 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid_legacy
) >= 0);
150 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ false, &iaid
) >= 0);
152 /* we expect, that the MAC address was hashed. The legacy value is in native
154 assert_se(iaid_legacy
== 0x8dde4ba8u
);
155 assert_se(iaid
== htole32(0x8dde4ba8u
));
156 #if __BYTE_ORDER == __LITTLE_ENDIAN
157 assert_se(iaid
== iaid_legacy
);
159 assert_se(iaid
== bswap_32(iaid_legacy
));
163 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
165 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
171 assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid
, &duid_len
) >= 0);
172 assert_se(dhcp_identifier_set_iaid(NULL
, &hw_addr
, /* legacy = */ true, &iaid
) >= 0);
174 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
175 assert_se(len
== 19);
176 assert_se(((uint8_t*) option
)[0] == 0xff);
178 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
179 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
190 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
192 _cleanup_free_ DHCPPacket
*discover
= NULL
;
193 uint16_t ip_check
, udp_check
;
198 size
= sizeof(DHCPPacket
);
199 assert_se(len
> size
);
201 discover
= memdup(packet
, len
);
203 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
204 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
205 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
206 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
207 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
208 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
210 ip_check
= discover
->ip
.check
;
212 discover
->ip
.ttl
= 0;
213 discover
->ip
.check
= discover
->udp
.len
;
215 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
216 assert_se(udp_check
== 0xffff);
218 discover
->ip
.ttl
= IPDEFTTL
;
219 discover
->ip
.check
= ip_check
;
221 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
222 assert_se(ip_check
== 0xffff);
224 assert_se(discover
->dhcp
.xid
);
225 assert_se(memcmp(discover
->dhcp
.chaddr
, hw_addr
.bytes
, hw_addr
.length
) == 0);
227 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
229 assert_se(callback_recv
);
230 callback_recv(size
, &discover
->dhcp
);
235 int dhcp_network_bind_raw_socket(
237 union sockaddr_union
*link
,
239 const struct hw_addr_data
*_hw_addr
,
240 const struct hw_addr_data
*_bcast_addr
,
243 bool so_priority_set
,
246 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
252 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
255 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
262 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
266 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
269 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
270 assert_se(res
== DHCP_DISCOVER
);
273 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
278 static void test_discover_message(sd_event
*e
) {
279 sd_dhcp_client
*client
;
283 printf("* %s\n", __func__
);
285 r
= sd_dhcp_client_new(&client
, false);
289 r
= sd_dhcp_client_attach_event(client
, e
, 0);
292 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
293 assert_se(sd_dhcp_client_set_mac(client
, hw_addr
.bytes
, bcast_addr
.bytes
, hw_addr
.length
, ARPHRD_ETHER
) >= 0);
294 dhcp_client_set_test_mode(client
, true);
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);
512 dhcp_client_set_test_mode(client
, true);
514 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
516 callback_recv
= test_addr_acq_recv_discover
;
518 assert_se(sd_event_add_time_relative(e
, NULL
, CLOCK_BOOTTIME
,
520 NULL
, INT_TO_PTR(-ETIMEDOUT
)) >= 0);
522 res
= sd_dhcp_client_start(client
);
523 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
525 assert_se(sd_event_loop(e
) >= 0);
527 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
528 assert_se(sd_dhcp_client_stop(client
) >= 0);
529 sd_dhcp_client_unref(client
);
531 test_fd
[1] = safe_close(test_fd
[1]);
533 callback_recv
= NULL
;
537 int main(int argc
, char *argv
[]) {
538 _cleanup_(sd_event_unrefp
) sd_event
*e
;
540 test_setup_logging(LOG_DEBUG
);
542 assert_se(sd_event_new(&e
) >= 0);
544 test_request_basic(e
);
545 test_request_anonymize(e
);
547 test_dhcp_identifier_set_iaid();
549 test_discover_message(e
);
552 #if HAVE_VALGRIND_VALGRIND_H
553 /* Make sure the async_close thread has finished.
554 * valgrind would report some of the phread_* structures
555 * as not cleaned up properly. */
556 if (RUNNING_ON_VALGRIND
)