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"
21 #include "random-util.h"
25 static uint8_t mac_addr
[] = {'A', 'B', 'C', '1', '2', '3'};
26 static uint8_t bcast_addr
[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
28 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
30 static bool verbose
= true;
31 static int test_fd
[2];
32 static test_callback_recv_t callback_recv
;
34 static sd_event_source
*test_hangcheck
;
36 static int test_dhcp_hangcheck(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
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_NAMESERVER
) == 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(42, mac_addr
, sizeof(mac_addr
), /* legacy = */ true,
150 /* use_mac = */ true, &iaid_legacy
) >= 0);
151 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, sizeof(mac_addr
), /* legacy = */ false,
152 /* use_mac = */ true, &iaid
) >= 0);
154 /* we expect, that the MAC address was hashed. The legacy value is in native
156 assert_se(iaid_legacy
== 0x8dde4ba8u
);
157 assert_se(iaid
== htole32(0x8dde4ba8u
));
158 #if __BYTE_ORDER == __LITTLE_ENDIAN
159 assert_se(iaid
== iaid_legacy
);
161 assert_se(iaid
== bswap_32(iaid_legacy
));
165 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
167 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
173 assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid
, &duid_len
) >= 0);
174 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, ETH_ALEN
, true, /* use_mac = */ true, &iaid
) >= 0);
176 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
177 assert_se(len
== 19);
178 assert_se(((uint8_t*) option
)[0] == 0xff);
180 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
181 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
192 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
194 _cleanup_free_ DHCPPacket
*discover
;
195 uint16_t ip_check
, udp_check
;
200 size
= sizeof(DHCPPacket
);
201 assert_se(len
> size
);
203 discover
= memdup(packet
, len
);
205 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
206 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
207 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
208 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
209 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
210 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
212 ip_check
= discover
->ip
.check
;
214 discover
->ip
.ttl
= 0;
215 discover
->ip
.check
= discover
->udp
.len
;
217 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
218 assert_se(udp_check
== 0xffff);
220 discover
->ip
.ttl
= IPDEFTTL
;
221 discover
->ip
.check
= ip_check
;
223 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
224 assert_se(ip_check
== 0xffff);
226 assert_se(discover
->dhcp
.xid
);
227 assert_se(memcmp(discover
->dhcp
.chaddr
, &mac_addr
, ETH_ALEN
) == 0);
229 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
231 assert_se(callback_recv
);
232 callback_recv(size
, &discover
->dhcp
);
237 int dhcp_network_bind_raw_socket(
239 union sockaddr_union
*link
,
241 const uint8_t *addr
, size_t addr_len
,
242 const uint8_t *bcaddr
, size_t bcaddr_len
,
243 uint16_t arp_type
, uint16_t port
) {
245 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
251 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
254 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
261 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
265 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
268 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
269 assert_se(res
== DHCP_DISCOVER
);
272 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
277 static void test_discover_message(sd_event
*e
) {
278 sd_dhcp_client
*client
;
282 printf("* %s\n", __func__
);
284 r
= sd_dhcp_client_new(&client
, false);
288 r
= sd_dhcp_client_attach_event(client
, e
, 0);
291 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
292 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, bcast_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
293 dhcp_client_set_test_mode(client
, true);
295 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
297 callback_recv
= test_discover_message_verify
;
299 res
= sd_dhcp_client_start(client
);
301 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
303 sd_event_run(e
, UINT64_MAX
);
305 sd_dhcp_client_stop(client
);
306 sd_dhcp_client_unref(client
);
308 test_fd
[1] = safe_close(test_fd
[1]);
310 callback_recv
= NULL
;
313 static uint8_t test_addr_acq_offer
[] = {
314 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
315 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
316 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
317 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
318 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
320 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
348 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
349 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
350 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
351 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
352 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
353 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 static uint8_t test_addr_acq_ack
[] = {
358 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
359 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
360 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
361 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
364 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
392 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
393 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
394 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
395 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
396 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
397 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 static int test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
403 sd_event
*e
= userdata
;
404 sd_dhcp_lease
*lease
;
406 const struct in_addr
*addrs
;
409 assert_se(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
411 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
414 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
415 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
416 sizeof(addr
.s_addr
)) == 0);
418 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
419 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
420 sizeof(addr
.s_addr
)) == 0);
422 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
423 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
424 sizeof(addrs
[0].s_addr
)) == 0);
427 printf(" DHCP address acquired\n");
434 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
435 uint16_t udp_check
= 0;
436 uint8_t *msg_bytes
= (uint8_t *)request
;
439 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
440 assert_se(res
== DHCP_REQUEST
);
441 assert_se(xid
== request
->xid
);
443 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
446 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
448 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
449 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
450 memcpy(&test_addr_acq_ack
[56], &mac_addr
, ETHER_ADDR_LEN
);
452 callback_recv
= NULL
;
454 res
= write(test_fd
[1], test_addr_acq_ack
,
455 sizeof(test_addr_acq_ack
));
456 assert_se(res
== sizeof(test_addr_acq_ack
));
459 printf(" send DHCP Ack\n");
464 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
465 uint16_t udp_check
= 0;
466 uint8_t *msg_bytes
= (uint8_t *)discover
;
469 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
470 assert_se(res
== DHCP_DISCOVER
);
472 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
477 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
479 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
480 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
481 memcpy(&test_addr_acq_offer
[56], &mac_addr
, ETHER_ADDR_LEN
);
483 callback_recv
= test_addr_acq_recv_request
;
485 res
= write(test_fd
[1], test_addr_acq_offer
,
486 sizeof(test_addr_acq_offer
));
487 assert_se(res
== sizeof(test_addr_acq_offer
));
490 printf(" sent DHCP Offer\n");
495 static void test_addr_acq(sd_event
*e
) {
496 sd_dhcp_client
*client
;
500 printf("* %s\n", __func__
);
502 r
= sd_dhcp_client_new(&client
, false);
506 r
= sd_dhcp_client_attach_event(client
, e
, 0);
509 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
510 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, bcast_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
511 dhcp_client_set_test_mode(client
, true);
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(
519 clock_boottime_or_monotonic(),
521 test_dhcp_hangcheck
, NULL
) >= 0);
523 res
= sd_dhcp_client_start(client
);
524 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
526 assert_se(sd_event_loop(e
) >= 0);
528 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
530 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
531 assert_se(sd_dhcp_client_stop(client
) >= 0);
532 sd_dhcp_client_unref(client
);
534 test_fd
[1] = safe_close(test_fd
[1]);
536 callback_recv
= NULL
;
540 int main(int argc
, char *argv
[]) {
541 _cleanup_(sd_event_unrefp
) sd_event
*e
;
543 test_setup_logging(LOG_DEBUG
);
545 assert_se(sd_event_new(&e
) >= 0);
547 test_request_basic(e
);
548 test_request_anonymize(e
);
550 test_dhcp_identifier_set_iaid();
552 test_discover_message(e
);
556 /* Make sure the async_close thread has finished.
557 * valgrind would report some of the phread_* structures
558 * as not cleaned up properly. */