1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2013 Intel Corporation. All rights reserved.
8 #include <sys/socket.h>
12 #include "sd-dhcp-client.h"
15 #include "alloc-util.h"
16 #include "dhcp-identifier.h"
17 #include "dhcp-internal.h"
18 #include "dhcp-protocol.h"
20 #include "random-util.h"
24 static uint8_t mac_addr
[] = {'A', 'B', 'C', '1', '2', '3'};
26 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
28 static bool verbose
= true;
29 static int test_fd
[2];
30 static test_callback_recv_t callback_recv
;
32 static sd_event_source
*test_hangcheck
;
34 static int test_dhcp_hangcheck(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
35 assert_not_reached("Test case should have completed in 2 seconds");
40 static void test_request_basic(sd_event
*e
) {
43 sd_dhcp_client
*client
;
46 printf("* %s\n", __FUNCTION__
);
48 /* Initialize client without Anonymize settings. */
49 r
= sd_dhcp_client_new(&client
, false);
54 r
= sd_dhcp_client_attach_event(client
, e
, 0);
57 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
58 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
59 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
61 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
62 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
63 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
64 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
65 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
67 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
68 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
69 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
70 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
71 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
73 assert_se(sd_dhcp_client_set_request_option(client
,
74 SD_DHCP_OPTION_SUBNET_MASK
) == -EEXIST
);
75 assert_se(sd_dhcp_client_set_request_option(client
,
76 SD_DHCP_OPTION_ROUTER
) == -EEXIST
);
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
,
80 SD_DHCP_OPTION_HOST_NAME
) == -EEXIST
);
81 assert_se(sd_dhcp_client_set_request_option(client
,
82 SD_DHCP_OPTION_DOMAIN_NAME
) == -EEXIST
);
83 assert_se(sd_dhcp_client_set_request_option(client
,
84 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == -EEXIST
);
86 assert_se(sd_dhcp_client_set_request_option(client
,
87 SD_DHCP_OPTION_PAD
) == -EINVAL
);
88 assert_se(sd_dhcp_client_set_request_option(client
,
89 SD_DHCP_OPTION_END
) == -EINVAL
);
90 assert_se(sd_dhcp_client_set_request_option(client
,
91 SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
92 assert_se(sd_dhcp_client_set_request_option(client
,
93 SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
94 assert_se(sd_dhcp_client_set_request_option(client
,
95 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
98 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
99 * default PRL when using Anonymize, so it is changed to other option
100 * that is not set by default, to check that it was set successfully.
101 * Options not set by default (using or not anonymize) are option 17
102 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
103 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
104 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
105 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 0);
106 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
108 sd_dhcp_client_unref(client
);
111 static void test_request_anonymize(sd_event
*e
) {
114 sd_dhcp_client
*client
;
117 printf("* %s\n", __FUNCTION__
);
119 /* Initialize client with Anonymize settings. */
120 r
= sd_dhcp_client_new(&client
, true);
125 r
= sd_dhcp_client_attach_event(client
, e
, 0);
128 assert_se(sd_dhcp_client_set_request_option(client
,
129 SD_DHCP_OPTION_NETBIOS_NAMESERVER
) == -EEXIST
);
130 /* This PRL option is not set when using Anonymize */
131 assert_se(sd_dhcp_client_set_request_option(client
,
132 SD_DHCP_OPTION_HOST_NAME
) == 0);
133 assert_se(sd_dhcp_client_set_request_option(client
,
134 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
137 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
138 * default PRL when using Anonymize, */
139 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
140 assert_se(sd_dhcp_client_set_request_option(client
, 101) == -EEXIST
);
142 sd_dhcp_client_unref(client
);
145 static void test_checksum(void) {
147 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
148 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0xff, 0xff, 0xff, 0xff
153 printf("* %s\n", __FUNCTION__
);
155 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
158 static void test_dhcp_identifier_set_iaid(void) {
159 uint32_t iaid_legacy
;
164 char ifname
[IFNAMSIZ
];
166 /* try to find an ifindex which does not exist. I causes dhcp_identifier_set_iaid()
167 * to hash the MAC address. */
168 pseudo_random_bytes(&ifindex
, sizeof(ifindex
));
169 if (ifindex
> 0 && !if_indextoname(ifindex
, ifname
))
173 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), true, &iaid_legacy
) >= 0);
174 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), false, &iaid
) >= 0);
176 /* we expect, that the MAC address was hashed. The legacy value is in native
178 assert_se(iaid_legacy
== 0x8dde4ba8u
);
179 assert_se(iaid
== htole32(0x8dde4ba8u
));
180 #if __BYTE_ORDER == __LITTLE_ENDIAN
181 assert_se(iaid
== iaid_legacy
);
183 assert_se(iaid
== __bswap_32(iaid_legacy
));
187 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
189 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
195 assert_se(dhcp_identifier_set_duid_en(&duid
, &duid_len
) >= 0);
196 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, ETH_ALEN
, true, &iaid
) >= 0);
198 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
199 assert_se(len
== 19);
200 assert_se(((uint8_t*) option
)[0] == 0xff);
202 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
203 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
214 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
216 _cleanup_free_ DHCPPacket
*discover
;
217 uint16_t ip_check
, udp_check
;
222 size
= sizeof(DHCPPacket
);
223 assert_se(len
> size
);
225 discover
= memdup(packet
, len
);
227 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
228 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
229 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
230 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
231 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
232 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
234 ip_check
= discover
->ip
.check
;
236 discover
->ip
.ttl
= 0;
237 discover
->ip
.check
= discover
->udp
.len
;
239 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
240 assert_se(udp_check
== 0xffff);
242 discover
->ip
.ttl
= IPDEFTTL
;
243 discover
->ip
.check
= ip_check
;
245 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
246 assert_se(ip_check
== 0xffff);
248 assert_se(discover
->dhcp
.xid
);
249 assert_se(memcmp(discover
->dhcp
.chaddr
, &mac_addr
, ETH_ALEN
) == 0);
251 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
253 assert_se(callback_recv
);
254 callback_recv(size
, &discover
->dhcp
);
259 int dhcp_network_bind_raw_socket(
261 union sockaddr_union
*link
,
263 const uint8_t *addr
, size_t addr_len
,
264 uint16_t arp_type
, uint16_t port
) {
266 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
272 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
) {
275 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
282 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
286 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
289 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
290 assert_se(res
== DHCP_DISCOVER
);
293 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
298 static void test_discover_message(sd_event
*e
) {
299 sd_dhcp_client
*client
;
303 printf("* %s\n", __FUNCTION__
);
305 r
= sd_dhcp_client_new(&client
, false);
309 r
= sd_dhcp_client_attach_event(client
, e
, 0);
312 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
313 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
315 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
317 callback_recv
= test_discover_message_verify
;
319 res
= sd_dhcp_client_start(client
);
321 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
323 sd_event_run(e
, (uint64_t) -1);
325 sd_dhcp_client_stop(client
);
326 sd_dhcp_client_unref(client
);
328 test_fd
[1] = safe_close(test_fd
[1]);
330 callback_recv
= NULL
;
333 static uint8_t test_addr_acq_offer
[] = {
334 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
335 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
336 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
337 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
338 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
340 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
368 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
369 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
370 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
371 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
372 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
373 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 static uint8_t test_addr_acq_ack
[] = {
378 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
379 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
380 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
381 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
384 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
412 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
413 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
414 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
415 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
416 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
417 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 static void test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
423 sd_event
*e
= userdata
;
424 sd_dhcp_lease
*lease
;
426 const struct in_addr
*addrs
;
429 assert_se(event
== SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
);
431 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
434 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
435 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
436 sizeof(addr
.s_addr
)) == 0);
438 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
439 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
440 sizeof(addr
.s_addr
)) == 0);
442 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
443 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
444 sizeof(addrs
[0].s_addr
)) == 0);
447 printf(" DHCP address acquired\n");
452 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
453 uint16_t udp_check
= 0;
454 uint8_t *msg_bytes
= (uint8_t *)request
;
457 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
458 assert_se(res
== DHCP_REQUEST
);
459 assert_se(xid
== request
->xid
);
461 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
464 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
466 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
467 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
468 memcpy(&test_addr_acq_ack
[56], &mac_addr
, ETHER_ADDR_LEN
);
470 callback_recv
= NULL
;
472 res
= write(test_fd
[1], test_addr_acq_ack
,
473 sizeof(test_addr_acq_ack
));
474 assert_se(res
== sizeof(test_addr_acq_ack
));
477 printf(" send DHCP Ack\n");
482 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
483 uint16_t udp_check
= 0;
484 uint8_t *msg_bytes
= (uint8_t *)discover
;
487 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
488 assert_se(res
== DHCP_DISCOVER
);
490 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
495 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
497 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
498 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
499 memcpy(&test_addr_acq_offer
[56], &mac_addr
, ETHER_ADDR_LEN
);
501 callback_recv
= test_addr_acq_recv_request
;
503 res
= write(test_fd
[1], test_addr_acq_offer
,
504 sizeof(test_addr_acq_offer
));
505 assert_se(res
== sizeof(test_addr_acq_offer
));
508 printf(" sent DHCP Offer\n");
513 static void test_addr_acq(sd_event
*e
) {
514 usec_t time_now
= now(clock_boottime_or_monotonic());
515 sd_dhcp_client
*client
;
519 printf("* %s\n", __FUNCTION__
);
521 r
= sd_dhcp_client_new(&client
, false);
525 r
= sd_dhcp_client_attach_event(client
, e
, 0);
528 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
529 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
531 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
533 callback_recv
= test_addr_acq_recv_discover
;
535 assert_se(sd_event_add_time(e
, &test_hangcheck
,
536 clock_boottime_or_monotonic(),
537 time_now
+ 2 * USEC_PER_SEC
, 0,
538 test_dhcp_hangcheck
, NULL
) >= 0);
540 res
= sd_dhcp_client_start(client
);
541 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
543 assert_se(sd_event_loop(e
) >= 0);
545 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
547 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
548 assert_se(sd_dhcp_client_stop(client
) >= 0);
549 sd_dhcp_client_unref(client
);
551 test_fd
[1] = safe_close(test_fd
[1]);
553 callback_recv
= NULL
;
557 int main(int argc
, char *argv
[]) {
558 _cleanup_(sd_event_unrefp
) sd_event
*e
;
560 test_setup_logging(LOG_DEBUG
);
562 assert_se(sd_event_new(&e
) >= 0);
564 test_request_basic(e
);
565 test_request_anonymize(e
);
567 test_dhcp_identifier_set_iaid();
569 test_discover_message(e
);
573 /* Make sure the async_close thread has finished.
574 * valgrind would report some of the phread_* structures
575 * as not cleaned up properly. */