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 int 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(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
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");
454 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
455 uint16_t udp_check
= 0;
456 uint8_t *msg_bytes
= (uint8_t *)request
;
459 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
460 assert_se(res
== DHCP_REQUEST
);
461 assert_se(xid
== request
->xid
);
463 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
466 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
468 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
469 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
470 memcpy(&test_addr_acq_ack
[56], &mac_addr
, ETHER_ADDR_LEN
);
472 callback_recv
= NULL
;
474 res
= write(test_fd
[1], test_addr_acq_ack
,
475 sizeof(test_addr_acq_ack
));
476 assert_se(res
== sizeof(test_addr_acq_ack
));
479 printf(" send DHCP Ack\n");
484 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
485 uint16_t udp_check
= 0;
486 uint8_t *msg_bytes
= (uint8_t *)discover
;
489 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
490 assert_se(res
== DHCP_DISCOVER
);
492 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
497 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
499 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
500 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
501 memcpy(&test_addr_acq_offer
[56], &mac_addr
, ETHER_ADDR_LEN
);
503 callback_recv
= test_addr_acq_recv_request
;
505 res
= write(test_fd
[1], test_addr_acq_offer
,
506 sizeof(test_addr_acq_offer
));
507 assert_se(res
== sizeof(test_addr_acq_offer
));
510 printf(" sent DHCP Offer\n");
515 static void test_addr_acq(sd_event
*e
) {
516 usec_t time_now
= now(clock_boottime_or_monotonic());
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(e
, &test_hangcheck
,
538 clock_boottime_or_monotonic(),
539 time_now
+ 2 * USEC_PER_SEC
, 0,
540 test_dhcp_hangcheck
, NULL
) >= 0);
542 res
= sd_dhcp_client_start(client
);
543 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
545 assert_se(sd_event_loop(e
) >= 0);
547 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
549 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
550 assert_se(sd_dhcp_client_stop(client
) >= 0);
551 sd_dhcp_client_unref(client
);
553 test_fd
[1] = safe_close(test_fd
[1]);
555 callback_recv
= NULL
;
559 int main(int argc
, char *argv
[]) {
560 _cleanup_(sd_event_unrefp
) sd_event
*e
;
562 test_setup_logging(LOG_DEBUG
);
564 assert_se(sd_event_new(&e
) >= 0);
566 test_request_basic(e
);
567 test_request_anonymize(e
);
569 test_dhcp_identifier_set_iaid();
571 test_discover_message(e
);
575 /* Make sure the async_close thread has finished.
576 * valgrind would report some of the phread_* structures
577 * as not cleaned up properly. */