1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright (C) 2013 Intel Corporation. All rights reserved.
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/socket.h>
26 #include "sd-dhcp-client.h"
29 #include "alloc-util.h"
30 #include "dhcp-identifier.h"
31 #include "dhcp-internal.h"
32 #include "dhcp-protocol.h"
36 static uint8_t mac_addr
[] = {'A', 'B', 'C', '1', '2', '3'};
38 typedef int (*test_callback_recv_t
)(size_t size
, DHCPMessage
*dhcp
);
40 static bool verbose
= true;
41 static int test_fd
[2];
42 static test_callback_recv_t callback_recv
;
44 static sd_event_source
*test_hangcheck
;
46 static int test_dhcp_hangcheck(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
47 assert_not_reached("Test case should have completed in 2 seconds");
52 static void test_request_basic(sd_event
*e
) {
55 sd_dhcp_client
*client
;
58 printf("* %s\n", __FUNCTION__
);
60 /* Initialize client without Anonymize settings. */
61 r
= sd_dhcp_client_new(&client
, false);
66 r
= sd_dhcp_client_attach_event(client
, e
, 0);
69 assert_se(sd_dhcp_client_set_request_option(NULL
, 0) == -EINVAL
);
70 assert_se(sd_dhcp_client_set_request_address(NULL
, NULL
) == -EINVAL
);
71 assert_se(sd_dhcp_client_set_ifindex(NULL
, 0) == -EINVAL
);
73 assert_se(sd_dhcp_client_set_ifindex(client
, 15) == 0);
74 assert_se(sd_dhcp_client_set_ifindex(client
, -42) == -EINVAL
);
75 assert_se(sd_dhcp_client_set_ifindex(client
, -1) == -EINVAL
);
76 assert_se(sd_dhcp_client_set_ifindex(client
, 0) == -EINVAL
);
77 assert_se(sd_dhcp_client_set_ifindex(client
, 1) == 0);
79 assert_se(sd_dhcp_client_set_hostname(client
, "host") == 1);
80 assert_se(sd_dhcp_client_set_hostname(client
, "host.domain") == 1);
81 assert_se(sd_dhcp_client_set_hostname(client
, NULL
) == 1);
82 assert_se(sd_dhcp_client_set_hostname(client
, "~host") == -EINVAL
);
83 assert_se(sd_dhcp_client_set_hostname(client
, "~host.domain") == -EINVAL
);
85 assert_se(sd_dhcp_client_set_request_option(client
,
86 SD_DHCP_OPTION_SUBNET_MASK
) == -EEXIST
);
87 assert_se(sd_dhcp_client_set_request_option(client
,
88 SD_DHCP_OPTION_ROUTER
) == -EEXIST
);
89 /* This PRL option is not set when using Anonymize, but in this test
90 * Anonymize settings are not being used. */
91 assert_se(sd_dhcp_client_set_request_option(client
,
92 SD_DHCP_OPTION_HOST_NAME
) == -EEXIST
);
93 assert_se(sd_dhcp_client_set_request_option(client
,
94 SD_DHCP_OPTION_DOMAIN_NAME
) == -EEXIST
);
95 assert_se(sd_dhcp_client_set_request_option(client
,
96 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
) == -EEXIST
);
98 assert_se(sd_dhcp_client_set_request_option(client
,
99 SD_DHCP_OPTION_PAD
) == -EINVAL
);
100 assert_se(sd_dhcp_client_set_request_option(client
,
101 SD_DHCP_OPTION_END
) == -EINVAL
);
102 assert_se(sd_dhcp_client_set_request_option(client
,
103 SD_DHCP_OPTION_MESSAGE_TYPE
) == -EINVAL
);
104 assert_se(sd_dhcp_client_set_request_option(client
,
105 SD_DHCP_OPTION_OVERLOAD
) == -EINVAL
);
106 assert_se(sd_dhcp_client_set_request_option(client
,
107 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
110 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
111 * default PRL when using Anonymize, so it is changed to other option
112 * that is not set by default, to check that it was set successfully.
113 * Options not set by default (using or not anonymize) are option 17
114 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
115 assert_se(sd_dhcp_client_set_request_option(client
, 17) == 0);
116 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
117 assert_se(sd_dhcp_client_set_request_option(client
, 42) == 0);
118 assert_se(sd_dhcp_client_set_request_option(client
, 17) == -EEXIST
);
120 sd_dhcp_client_unref(client
);
123 static void test_request_anonymize(sd_event
*e
) {
126 sd_dhcp_client
*client
;
129 printf("* %s\n", __FUNCTION__
);
131 /* Initialize client with Anonymize settings. */
132 r
= sd_dhcp_client_new(&client
, true);
137 r
= sd_dhcp_client_attach_event(client
, e
, 0);
140 assert_se(sd_dhcp_client_set_request_option(client
,
141 SD_DHCP_OPTION_NETBIOS_NAMESERVER
) == -EEXIST
);
142 /* This PRL option is not set when using Anonymize */
143 assert_se(sd_dhcp_client_set_request_option(client
,
144 SD_DHCP_OPTION_HOST_NAME
) == 0);
145 assert_se(sd_dhcp_client_set_request_option(client
,
146 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
)
149 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
150 * default PRL when using Anonymize, */
151 assert_se(sd_dhcp_client_set_request_option(client
, 101) == 0);
152 assert_se(sd_dhcp_client_set_request_option(client
, 101) == -EEXIST
);
154 sd_dhcp_client_unref(client
);
157 static void test_checksum(void) {
159 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
160 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0xff, 0xff, 0xff, 0xff
165 printf("* %s\n", __FUNCTION__
);
167 assert_se(dhcp_packet_checksum((uint8_t*)&buf
, 20) == be16toh(0x78ae));
170 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
172 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
178 assert_se(dhcp_identifier_set_duid_en(&duid
, &duid_len
) >= 0);
179 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, ETH_ALEN
, &iaid
) >= 0);
181 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
182 assert_se(len
== 19);
183 assert_se(((uint8_t*) option
)[0] == 0xff);
185 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
186 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
197 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
199 _cleanup_free_ DHCPPacket
*discover
;
200 uint16_t ip_check
, udp_check
;
205 size
= sizeof(DHCPPacket
);
206 assert_se(len
> size
);
208 discover
= memdup(packet
, len
);
210 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
211 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
212 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
213 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
214 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
215 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
217 ip_check
= discover
->ip
.check
;
219 discover
->ip
.ttl
= 0;
220 discover
->ip
.check
= discover
->udp
.len
;
222 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
223 assert_se(udp_check
== 0xffff);
225 discover
->ip
.ttl
= IPDEFTTL
;
226 discover
->ip
.check
= ip_check
;
228 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
229 assert_se(ip_check
== 0xffff);
231 assert_se(discover
->dhcp
.xid
);
232 assert_se(memcmp(discover
->dhcp
.chaddr
, &mac_addr
, ETH_ALEN
) == 0);
234 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
236 assert_se(callback_recv
);
237 callback_recv(size
, &discover
->dhcp
);
242 int dhcp_network_bind_raw_socket(
244 union sockaddr_union
*link
,
246 const uint8_t *addr
, size_t addr_len
,
247 uint16_t arp_type
, uint16_t port
) {
249 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, test_fd
) < 0)
255 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
) {
258 fd
= socket(AF_INET
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
265 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
269 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
272 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
273 assert_se(res
== DHCP_DISCOVER
);
276 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
281 static void test_discover_message(sd_event
*e
) {
282 sd_dhcp_client
*client
;
286 printf("* %s\n", __FUNCTION__
);
288 r
= sd_dhcp_client_new(&client
, false);
292 r
= sd_dhcp_client_attach_event(client
, e
, 0);
295 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
296 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
298 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
300 callback_recv
= test_discover_message_verify
;
302 res
= sd_dhcp_client_start(client
);
304 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
306 sd_event_run(e
, (uint64_t) -1);
308 sd_dhcp_client_stop(client
);
309 sd_dhcp_client_unref(client
);
311 test_fd
[1] = safe_close(test_fd
[1]);
313 callback_recv
= NULL
;
316 static uint8_t test_addr_acq_offer
[] = {
317 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
318 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
319 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
320 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
321 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
323 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
351 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
352 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
353 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
354 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
355 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
356 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 static uint8_t test_addr_acq_ack
[] = {
361 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
362 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
363 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
364 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
367 0xc0, 0xa8, 0x02, 0x01, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
395 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
396 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
397 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
398 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
399 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
400 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 static void test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
406 sd_event
*e
= userdata
;
407 sd_dhcp_lease
*lease
;
411 assert_se(event
== SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
);
413 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
416 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
417 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
418 sizeof(addr
.s_addr
)) == 0);
420 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
421 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
422 sizeof(addr
.s_addr
)) == 0);
424 assert_se(sd_dhcp_lease_get_router(lease
, &addr
) >= 0);
425 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[308],
426 sizeof(addr
.s_addr
)) == 0);
429 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 usec_t time_now
= now(clock_boottime_or_monotonic());
497 sd_dhcp_client
*client
;
501 printf("* %s\n", __FUNCTION__
);
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
, mac_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
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(e
, &test_hangcheck
,
518 clock_boottime_or_monotonic(),
519 time_now
+ 2 * USEC_PER_SEC
, 0,
520 test_dhcp_hangcheck
, NULL
) >= 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 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
529 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
530 assert_se(sd_dhcp_client_stop(client
) >= 0);
531 sd_dhcp_client_unref(client
);
533 test_fd
[1] = safe_close(test_fd
[1]);
535 callback_recv
= NULL
;
539 int main(int argc
, char *argv
[]) {
540 _cleanup_(sd_event_unrefp
) sd_event
*e
;
542 log_set_max_level(LOG_DEBUG
);
543 log_parse_environment();
546 assert_se(sd_event_new(&e
) >= 0);
548 test_request_basic(e
);
549 test_request_anonymize(e
);
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. */