1 /* SPDX-License-Identifier: LGPL-2.1+ */
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'};
27 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
29 static bool verbose
= true;
30 static int test_fd
[2];
31 static test_callback_recv_t callback_recv
;
33 static sd_event_source
*test_hangcheck
;
35 static int test_dhcp_hangcheck(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
36 assert_not_reached("Test case should have completed in 2 seconds");
41 static void test_request_basic(sd_event
*e
) {
44 sd_dhcp_client
*client
;
47 printf("* %s\n", __FUNCTION__
);
49 /* Initialize client without Anonymize settings. */
50 r
= sd_dhcp_client_new(&client
, false);
55 r
= sd_dhcp_client_attach_event(client
, e
, 0);
58 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
59 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
60 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
62 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
63 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
64 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
65 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
66 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
68 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
69 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
70 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
71 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
72 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
74 assert_se(sd_dhcp_client_set_request_option(client
,
75 SD_DHCP_OPTION_SUBNET_MASK
) == -EEXIST
);
76 assert_se(sd_dhcp_client_set_request_option(client
,
77 SD_DHCP_OPTION_ROUTER
) == -EEXIST
);
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
,
81 SD_DHCP_OPTION_HOST_NAME
) == -EEXIST
);
82 assert_se(sd_dhcp_client_set_request_option(client
,
83 SD_DHCP_OPTION_DOMAIN_NAME
) == -EEXIST
);
84 assert_se(sd_dhcp_client_set_request_option(client
,
85 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == -EEXIST
);
87 assert_se(sd_dhcp_client_set_request_option(client
,
88 SD_DHCP_OPTION_PAD
) == -EINVAL
);
89 assert_se(sd_dhcp_client_set_request_option(client
,
90 SD_DHCP_OPTION_END
) == -EINVAL
);
91 assert_se(sd_dhcp_client_set_request_option(client
,
92 SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
93 assert_se(sd_dhcp_client_set_request_option(client
,
94 SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
95 assert_se(sd_dhcp_client_set_request_option(client
,
96 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
99 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
100 * default PRL when using Anonymize, so it is changed to other option
101 * that is not set by default, to check that it was set successfully.
102 * Options not set by default (using or not anonymize) are option 17
103 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
104 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
105 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
106 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 0);
107 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
109 sd_dhcp_client_unref(client
);
112 static void test_request_anonymize(sd_event
*e
) {
115 sd_dhcp_client
*client
;
118 printf("* %s\n", __FUNCTION__
);
120 /* Initialize client with Anonymize settings. */
121 r
= sd_dhcp_client_new(&client
, true);
126 r
= sd_dhcp_client_attach_event(client
, e
, 0);
129 assert_se(sd_dhcp_client_set_request_option(client
,
130 SD_DHCP_OPTION_NETBIOS_NAMESERVER
) == -EEXIST
);
131 /* This PRL option is not set when using Anonymize */
132 assert_se(sd_dhcp_client_set_request_option(client
,
133 SD_DHCP_OPTION_HOST_NAME
) == 0);
134 assert_se(sd_dhcp_client_set_request_option(client
,
135 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
138 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
139 * default PRL when using Anonymize, */
140 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
141 assert_se(sd_dhcp_client_set_request_option(client
, 101) == -EEXIST
);
143 sd_dhcp_client_unref(client
);
146 static void test_checksum(void) {
148 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
149 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0xff, 0xff, 0xff, 0xff
154 printf("* %s\n", __FUNCTION__
);
156 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
159 static void test_dhcp_identifier_set_iaid(void) {
160 uint32_t iaid_legacy
;
165 char ifname
[IFNAMSIZ
];
167 /* try to find an ifindex which does not exist. I causes dhcp_identifier_set_iaid()
168 * to hash the MAC address. */
169 pseudo_random_bytes(&ifindex
, sizeof(ifindex
));
170 if (ifindex
> 0 && !if_indextoname(ifindex
, ifname
))
174 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), true, &iaid_legacy
) >= 0);
175 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), false, &iaid
) >= 0);
177 /* we expect, that the MAC address was hashed. The legacy value is in native
179 assert_se(iaid_legacy
== 0x8dde4ba8u
);
180 assert_se(iaid
== htole32(0x8dde4ba8u
));
181 #if __BYTE_ORDER == __LITTLE_ENDIAN
182 assert_se(iaid
== iaid_legacy
);
184 assert_se(iaid
== __bswap_32(iaid_legacy
));
188 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
190 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
196 assert_se(dhcp_identifier_set_duid_en(&duid
, &duid_len
) >= 0);
197 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, ETH_ALEN
, true, &iaid
) >= 0);
199 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
200 assert_se(len
== 19);
201 assert_se(((uint8_t*) option
)[0] == 0xff);
203 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
204 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
215 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
217 _cleanup_free_ DHCPPacket
*discover
;
218 uint16_t ip_check
, udp_check
;
223 size
= sizeof(DHCPPacket
);
224 assert_se(len
> size
);
226 discover
= memdup(packet
, len
);
228 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
229 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
230 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
231 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
232 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
233 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
235 ip_check
= discover
->ip
.check
;
237 discover
->ip
.ttl
= 0;
238 discover
->ip
.check
= discover
->udp
.len
;
240 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
241 assert_se(udp_check
== 0xffff);
243 discover
->ip
.ttl
= IPDEFTTL
;
244 discover
->ip
.check
= ip_check
;
246 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
247 assert_se(ip_check
== 0xffff);
249 assert_se(discover
->dhcp
.xid
);
250 assert_se(memcmp(discover
->dhcp
.chaddr
, &mac_addr
, ETH_ALEN
) == 0);
252 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
254 assert_se(callback_recv
);
255 callback_recv(size
, &discover
->dhcp
);
260 int dhcp_network_bind_raw_socket(
262 union sockaddr_union
*link
,
264 const uint8_t *addr
, size_t addr_len
,
265 uint16_t arp_type
, uint16_t port
) {
267 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
273 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
276 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
283 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
287 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
290 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
291 assert_se(res
== DHCP_DISCOVER
);
294 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
299 static void test_discover_message(sd_event
*e
) {
300 sd_dhcp_client
*client
;
304 printf("* %s\n", __FUNCTION__
);
306 r
= sd_dhcp_client_new(&client
, false);
310 r
= sd_dhcp_client_attach_event(client
, e
, 0);
313 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
314 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
316 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
318 callback_recv
= test_discover_message_verify
;
320 res
= sd_dhcp_client_start(client
);
322 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
324 sd_event_run(e
, (uint64_t) -1);
326 sd_dhcp_client_stop(client
);
327 sd_dhcp_client_unref(client
);
329 test_fd
[1] = safe_close(test_fd
[1]);
331 callback_recv
= NULL
;
334 static uint8_t test_addr_acq_offer
[] = {
335 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
336 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
337 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
338 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
339 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
341 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
369 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
370 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
371 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
372 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
373 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
374 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 static uint8_t test_addr_acq_ack
[] = {
379 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
380 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
381 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
382 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
385 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
413 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
414 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
415 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
416 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
417 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
418 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 static int test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
424 sd_event
*e
= userdata
;
425 sd_dhcp_lease
*lease
;
427 const struct in_addr
*addrs
;
430 assert_se(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
432 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
435 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
436 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
437 sizeof(addr
.s_addr
)) == 0);
439 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
440 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
441 sizeof(addr
.s_addr
)) == 0);
443 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
444 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
445 sizeof(addrs
[0].s_addr
)) == 0);
448 printf(" DHCP address acquired\n");
455 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
456 uint16_t udp_check
= 0;
457 uint8_t *msg_bytes
= (uint8_t *)request
;
460 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
461 assert_se(res
== DHCP_REQUEST
);
462 assert_se(xid
== request
->xid
);
464 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
467 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
469 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
470 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
471 memcpy(&test_addr_acq_ack
[56], &mac_addr
, ETHER_ADDR_LEN
);
473 callback_recv
= NULL
;
475 res
= write(test_fd
[1], test_addr_acq_ack
,
476 sizeof(test_addr_acq_ack
));
477 assert_se(res
== sizeof(test_addr_acq_ack
));
480 printf(" send DHCP Ack\n");
485 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
486 uint16_t udp_check
= 0;
487 uint8_t *msg_bytes
= (uint8_t *)discover
;
490 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
491 assert_se(res
== DHCP_DISCOVER
);
493 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
498 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
500 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
501 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
502 memcpy(&test_addr_acq_offer
[56], &mac_addr
, ETHER_ADDR_LEN
);
504 callback_recv
= test_addr_acq_recv_request
;
506 res
= write(test_fd
[1], test_addr_acq_offer
,
507 sizeof(test_addr_acq_offer
));
508 assert_se(res
== sizeof(test_addr_acq_offer
));
511 printf(" sent DHCP Offer\n");
516 static void test_addr_acq(sd_event
*e
) {
517 sd_dhcp_client
*client
;
521 printf("* %s\n", __FUNCTION__
);
523 r
= sd_dhcp_client_new(&client
, false);
527 r
= sd_dhcp_client_attach_event(client
, e
, 0);
530 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
531 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
533 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
535 callback_recv
= test_addr_acq_recv_discover
;
537 assert_se(sd_event_add_time_relative(
539 clock_boottime_or_monotonic(),
541 test_dhcp_hangcheck
, NULL
) >= 0);
543 res
= sd_dhcp_client_start(client
);
544 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
546 assert_se(sd_event_loop(e
) >= 0);
548 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
550 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
551 assert_se(sd_dhcp_client_stop(client
) >= 0);
552 sd_dhcp_client_unref(client
);
554 test_fd
[1] = safe_close(test_fd
[1]);
556 callback_recv
= NULL
;
560 int main(int argc
, char *argv
[]) {
561 _cleanup_(sd_event_unrefp
) sd_event
*e
;
563 test_setup_logging(LOG_DEBUG
);
565 assert_se(sd_event_new(&e
) >= 0);
567 test_request_basic(e
);
568 test_request_anonymize(e
);
570 test_dhcp_identifier_set_iaid();
572 test_discover_message(e
);
576 /* Make sure the async_close thread has finished.
577 * valgrind would report some of the phread_* structures
578 * as not cleaned up properly. */