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
) {
37 assert_not_reached("Test case should have completed in 2 seconds");
42 static void test_request_basic(sd_event
*e
) {
45 sd_dhcp_client
*client
;
48 printf("* %s\n", __FUNCTION__
);
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", __FUNCTION__
);
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", __FUNCTION__
);
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
;
151 char ifname
[IFNAMSIZ
];
153 /* try to find an ifindex which does not exist. I causes dhcp_identifier_set_iaid()
154 * to hash the MAC address. */
155 pseudo_random_bytes(&ifindex
, sizeof(ifindex
));
156 if (ifindex
> 0 && !if_indextoname(ifindex
, ifname
))
160 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), true, &iaid_legacy
) >= 0);
161 assert_se(dhcp_identifier_set_iaid(ifindex
, mac_addr
, sizeof(mac_addr
), false, &iaid
) >= 0);
163 /* we expect, that the MAC address was hashed. The legacy value is in native
165 assert_se(iaid_legacy
== 0x8dde4ba8u
);
166 assert_se(iaid
== htole32(0x8dde4ba8u
));
167 #if __BYTE_ORDER == __LITTLE_ENDIAN
168 assert_se(iaid
== iaid_legacy
);
170 assert_se(iaid
== __bswap_32(iaid_legacy
));
174 static int check_options(uint8_t code
, uint8_t len
, const void *option
, void *userdata
) {
176 case SD_DHCP_OPTION_CLIENT_IDENTIFIER
:
182 assert_se(dhcp_identifier_set_duid_en(&duid
, &duid_len
) >= 0);
183 assert_se(dhcp_identifier_set_iaid(42, mac_addr
, ETH_ALEN
, true, &iaid
) >= 0);
185 assert_se(len
== sizeof(uint8_t) + sizeof(uint32_t) + duid_len
);
186 assert_se(len
== 19);
187 assert_se(((uint8_t*) option
)[0] == 0xff);
189 assert_se(memcmp((uint8_t*) option
+ 1, &iaid
, sizeof(iaid
)) == 0);
190 assert_se(memcmp((uint8_t*) option
+ 5, &duid
, duid_len
) == 0);
201 int dhcp_network_send_raw_socket(int s
, const union sockaddr_union
*link
, const void *packet
, size_t len
) {
203 _cleanup_free_ DHCPPacket
*discover
;
204 uint16_t ip_check
, udp_check
;
209 size
= sizeof(DHCPPacket
);
210 assert_se(len
> size
);
212 discover
= memdup(packet
, len
);
214 assert_se(discover
->ip
.ttl
== IPDEFTTL
);
215 assert_se(discover
->ip
.protocol
== IPPROTO_UDP
);
216 assert_se(discover
->ip
.saddr
== INADDR_ANY
);
217 assert_se(discover
->ip
.daddr
== INADDR_BROADCAST
);
218 assert_se(discover
->udp
.source
== be16toh(DHCP_PORT_CLIENT
));
219 assert_se(discover
->udp
.dest
== be16toh(DHCP_PORT_SERVER
));
221 ip_check
= discover
->ip
.check
;
223 discover
->ip
.ttl
= 0;
224 discover
->ip
.check
= discover
->udp
.len
;
226 udp_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
.ttl
, len
- 8);
227 assert_se(udp_check
== 0xffff);
229 discover
->ip
.ttl
= IPDEFTTL
;
230 discover
->ip
.check
= ip_check
;
232 ip_check
= ~dhcp_packet_checksum((uint8_t*)&discover
->ip
, sizeof(discover
->ip
));
233 assert_se(ip_check
== 0xffff);
235 assert_se(discover
->dhcp
.xid
);
236 assert_se(memcmp(discover
->dhcp
.chaddr
, &mac_addr
, ETH_ALEN
) == 0);
238 size
= len
- sizeof(struct iphdr
) - sizeof(struct udphdr
);
240 assert_se(callback_recv
);
241 callback_recv(size
, &discover
->dhcp
);
246 int dhcp_network_bind_raw_socket(
248 union sockaddr_union
*link
,
250 const uint8_t *addr
, size_t addr_len
,
251 const uint8_t *bcaddr
, size_t bcaddr_len
,
252 uint16_t arp_type
, uint16_t port
) {
254 if (socketpair(AF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
260 int dhcp_network_bind_udp_socket(int ifindex
, be32_t address
, uint16_t port
, int ip_service_type
) {
263 fd
= socket(AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
270 int dhcp_network_send_udp_socket(int s
, be32_t address
, uint16_t port
, const void *packet
, size_t len
) {
274 static int test_discover_message_verify(size_t size
, struct DHCPMessage
*dhcp
) {
277 res
= dhcp_option_parse(dhcp
, size
, check_options
, NULL
, NULL
);
278 assert_se(res
== DHCP_DISCOVER
);
281 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp
->xid
));
286 static void test_discover_message(sd_event
*e
) {
287 sd_dhcp_client
*client
;
291 printf("* %s\n", __FUNCTION__
);
293 r
= sd_dhcp_client_new(&client
, false);
297 r
= sd_dhcp_client_attach_event(client
, e
, 0);
300 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
301 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, bcast_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
303 assert_se(sd_dhcp_client_set_request_option(client
, 248) >= 0);
305 callback_recv
= test_discover_message_verify
;
307 res
= sd_dhcp_client_start(client
);
309 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
311 sd_event_run(e
, UINT64_MAX
);
313 sd_dhcp_client_stop(client
);
314 sd_dhcp_client_unref(client
);
316 test_fd
[1] = safe_close(test_fd
[1]);
318 callback_recv
= NULL
;
321 static uint8_t test_addr_acq_offer
[] = {
322 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
323 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
324 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
325 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
326 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
328 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
356 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
357 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
358 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
359 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
360 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
361 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 static uint8_t test_addr_acq_ack
[] = {
366 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
367 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
368 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
369 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
372 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
400 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
401 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
402 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
403 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
404 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
405 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 static int test_addr_acq_acquired(sd_dhcp_client
*client
, int event
,
411 sd_event
*e
= userdata
;
412 sd_dhcp_lease
*lease
;
414 const struct in_addr
*addrs
;
417 assert_se(IN_SET(event
, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
, SD_DHCP_CLIENT_EVENT_SELECTING
));
419 assert_se(sd_dhcp_client_get_lease(client
, &lease
) >= 0);
422 assert_se(sd_dhcp_lease_get_address(lease
, &addr
) >= 0);
423 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[44],
424 sizeof(addr
.s_addr
)) == 0);
426 assert_se(sd_dhcp_lease_get_netmask(lease
, &addr
) >= 0);
427 assert_se(memcmp(&addr
.s_addr
, &test_addr_acq_ack
[285],
428 sizeof(addr
.s_addr
)) == 0);
430 assert_se(sd_dhcp_lease_get_router(lease
, &addrs
) == 1);
431 assert_se(memcmp(&addrs
[0].s_addr
, &test_addr_acq_ack
[308],
432 sizeof(addrs
[0].s_addr
)) == 0);
435 printf(" DHCP address acquired\n");
442 static int test_addr_acq_recv_request(size_t size
, DHCPMessage
*request
) {
443 uint16_t udp_check
= 0;
444 uint8_t *msg_bytes
= (uint8_t *)request
;
447 res
= dhcp_option_parse(request
, size
, check_options
, NULL
, NULL
);
448 assert_se(res
== DHCP_REQUEST
);
449 assert_se(xid
== request
->xid
);
451 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
454 printf(" recv DHCP Request 0x%08x\n", be32toh(xid
));
456 memcpy(&test_addr_acq_ack
[26], &udp_check
, sizeof(udp_check
));
457 memcpy(&test_addr_acq_ack
[32], &xid
, sizeof(xid
));
458 memcpy(&test_addr_acq_ack
[56], &mac_addr
, ETHER_ADDR_LEN
);
460 callback_recv
= NULL
;
462 res
= write(test_fd
[1], test_addr_acq_ack
,
463 sizeof(test_addr_acq_ack
));
464 assert_se(res
== sizeof(test_addr_acq_ack
));
467 printf(" send DHCP Ack\n");
472 static int test_addr_acq_recv_discover(size_t size
, DHCPMessage
*discover
) {
473 uint16_t udp_check
= 0;
474 uint8_t *msg_bytes
= (uint8_t *)discover
;
477 res
= dhcp_option_parse(discover
, size
, check_options
, NULL
, NULL
);
478 assert_se(res
== DHCP_DISCOVER
);
480 assert_se(msg_bytes
[size
- 1] == SD_DHCP_OPTION_END
);
485 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid
));
487 memcpy(&test_addr_acq_offer
[26], &udp_check
, sizeof(udp_check
));
488 memcpy(&test_addr_acq_offer
[32], &xid
, sizeof(xid
));
489 memcpy(&test_addr_acq_offer
[56], &mac_addr
, ETHER_ADDR_LEN
);
491 callback_recv
= test_addr_acq_recv_request
;
493 res
= write(test_fd
[1], test_addr_acq_offer
,
494 sizeof(test_addr_acq_offer
));
495 assert_se(res
== sizeof(test_addr_acq_offer
));
498 printf(" sent DHCP Offer\n");
503 static void test_addr_acq(sd_event
*e
) {
504 sd_dhcp_client
*client
;
508 printf("* %s\n", __FUNCTION__
);
510 r
= sd_dhcp_client_new(&client
, false);
514 r
= sd_dhcp_client_attach_event(client
, e
, 0);
517 assert_se(sd_dhcp_client_set_ifindex(client
, 42) >= 0);
518 assert_se(sd_dhcp_client_set_mac(client
, mac_addr
, bcast_addr
, ETH_ALEN
, ARPHRD_ETHER
) >= 0);
520 assert_se(sd_dhcp_client_set_callback(client
, test_addr_acq_acquired
, e
) >= 0);
522 callback_recv
= test_addr_acq_recv_discover
;
524 assert_se(sd_event_add_time_relative(
526 clock_boottime_or_monotonic(),
528 test_dhcp_hangcheck
, NULL
) >= 0);
530 res
= sd_dhcp_client_start(client
);
531 assert_se(IN_SET(res
, 0, -EINPROGRESS
));
533 assert_se(sd_event_loop(e
) >= 0);
535 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
537 assert_se(sd_dhcp_client_set_callback(client
, NULL
, NULL
) >= 0);
538 assert_se(sd_dhcp_client_stop(client
) >= 0);
539 sd_dhcp_client_unref(client
);
541 test_fd
[1] = safe_close(test_fd
[1]);
543 callback_recv
= NULL
;
547 int main(int argc
, char *argv
[]) {
548 _cleanup_(sd_event_unrefp
) sd_event
*e
;
550 test_setup_logging(LOG_DEBUG
);
552 assert_se(sd_event_new(&e
) >= 0);
554 test_request_basic(e
);
555 test_request_anonymize(e
);
557 test_dhcp_identifier_set_iaid();
559 test_discover_message(e
);
563 /* Make sure the async_close thread has finished.
564 * valgrind would report some of the phread_* structures
565 * as not cleaned up properly. */