]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/test-dhcp-client.c
Merge the "boot loader specification" wiki page
[thirdparty/systemd.git] / src / libsystemd-network / test-dhcp-client.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2013 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <errno.h>
7 #include <stdio.h>
8 #include <sys/socket.h>
9 #include <unistd.h>
10
11 #include "sd-dhcp-client.h"
12 #include "sd-event.h"
13
14 #include "alloc-util.h"
15 #include "dhcp-identifier.h"
16 #include "dhcp-internal.h"
17 #include "dhcp-protocol.h"
18 #include "fd-util.h"
19 #include "util.h"
20
21 static uint8_t mac_addr[] = {'A', 'B', 'C', '1', '2', '3'};
22
23 typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
24
25 static bool verbose = true;
26 static int test_fd[2];
27 static test_callback_recv_t callback_recv;
28 static be32_t xid;
29 static sd_event_source *test_hangcheck;
30
31 static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
32 assert_not_reached("Test case should have completed in 2 seconds");
33
34 return 0;
35 }
36
37 static void test_request_basic(sd_event *e) {
38 int r;
39
40 sd_dhcp_client *client;
41
42 if (verbose)
43 printf("* %s\n", __FUNCTION__);
44
45 /* Initialize client without Anonymize settings. */
46 r = sd_dhcp_client_new(&client, false);
47
48 assert_se(r >= 0);
49 assert_se(client);
50
51 r = sd_dhcp_client_attach_event(client, e, 0);
52 assert_se(r >= 0);
53
54 assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
55 assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
56 assert_se(sd_dhcp_client_set_ifindex(NULL, 0) == -EINVAL);
57
58 assert_se(sd_dhcp_client_set_ifindex(client, 15) == 0);
59 assert_se(sd_dhcp_client_set_ifindex(client, -42) == -EINVAL);
60 assert_se(sd_dhcp_client_set_ifindex(client, -1) == -EINVAL);
61 assert_se(sd_dhcp_client_set_ifindex(client, 0) == -EINVAL);
62 assert_se(sd_dhcp_client_set_ifindex(client, 1) == 0);
63
64 assert_se(sd_dhcp_client_set_hostname(client, "host") == 1);
65 assert_se(sd_dhcp_client_set_hostname(client, "host.domain") == 1);
66 assert_se(sd_dhcp_client_set_hostname(client, NULL) == 1);
67 assert_se(sd_dhcp_client_set_hostname(client, "~host") == -EINVAL);
68 assert_se(sd_dhcp_client_set_hostname(client, "~host.domain") == -EINVAL);
69
70 assert_se(sd_dhcp_client_set_request_option(client,
71 SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST);
72 assert_se(sd_dhcp_client_set_request_option(client,
73 SD_DHCP_OPTION_ROUTER) == -EEXIST);
74 /* This PRL option is not set when using Anonymize, but in this test
75 * Anonymize settings are not being used. */
76 assert_se(sd_dhcp_client_set_request_option(client,
77 SD_DHCP_OPTION_HOST_NAME) == -EEXIST);
78 assert_se(sd_dhcp_client_set_request_option(client,
79 SD_DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
80 assert_se(sd_dhcp_client_set_request_option(client,
81 SD_DHCP_OPTION_DOMAIN_NAME_SERVER) == -EEXIST);
82
83 assert_se(sd_dhcp_client_set_request_option(client,
84 SD_DHCP_OPTION_PAD) == -EINVAL);
85 assert_se(sd_dhcp_client_set_request_option(client,
86 SD_DHCP_OPTION_END) == -EINVAL);
87 assert_se(sd_dhcp_client_set_request_option(client,
88 SD_DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
89 assert_se(sd_dhcp_client_set_request_option(client,
90 SD_DHCP_OPTION_OVERLOAD) == -EINVAL);
91 assert_se(sd_dhcp_client_set_request_option(client,
92 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST)
93 == -EINVAL);
94
95 /* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
96 * default PRL when using Anonymize, so it is changed to other option
97 * that is not set by default, to check that it was set successfully.
98 * Options not set by default (using or not anonymize) are option 17
99 * (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
100 assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
101 assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
102 assert_se(sd_dhcp_client_set_request_option(client, 42) == 0);
103 assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
104
105 sd_dhcp_client_unref(client);
106 }
107
108 static void test_request_anonymize(sd_event *e) {
109 int r;
110
111 sd_dhcp_client *client;
112
113 if (verbose)
114 printf("* %s\n", __FUNCTION__);
115
116 /* Initialize client with Anonymize settings. */
117 r = sd_dhcp_client_new(&client, true);
118
119 assert_se(r >= 0);
120 assert_se(client);
121
122 r = sd_dhcp_client_attach_event(client, e, 0);
123 assert_se(r >= 0);
124
125 assert_se(sd_dhcp_client_set_request_option(client,
126 SD_DHCP_OPTION_NETBIOS_NAMESERVER) == -EEXIST);
127 /* This PRL option is not set when using Anonymize */
128 assert_se(sd_dhcp_client_set_request_option(client,
129 SD_DHCP_OPTION_HOST_NAME) == 0);
130 assert_se(sd_dhcp_client_set_request_option(client,
131 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST)
132 == -EINVAL);
133
134 /* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
135 * default PRL when using Anonymize, */
136 assert_se(sd_dhcp_client_set_request_option(client, 101) == 0);
137 assert_se(sd_dhcp_client_set_request_option(client, 101) == -EEXIST);
138
139 sd_dhcp_client_unref(client);
140 }
141
142 static void test_checksum(void) {
143 uint8_t buf[20] = {
144 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
145 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0xff, 0xff, 0xff, 0xff
147 };
148
149 if (verbose)
150 printf("* %s\n", __FUNCTION__);
151
152 assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
153 }
154
155 static int check_options(uint8_t code, uint8_t len, const void *option, void *userdata) {
156 switch(code) {
157 case SD_DHCP_OPTION_CLIENT_IDENTIFIER:
158 {
159 uint32_t iaid;
160 struct duid duid;
161 size_t duid_len;
162
163 assert_se(dhcp_identifier_set_duid_en(&duid, &duid_len) >= 0);
164 assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, &iaid) >= 0);
165
166 assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
167 assert_se(len == 19);
168 assert_se(((uint8_t*) option)[0] == 0xff);
169
170 assert_se(memcmp((uint8_t*) option + 1, &iaid, sizeof(iaid)) == 0);
171 assert_se(memcmp((uint8_t*) option + 5, &duid, duid_len) == 0);
172 break;
173 }
174
175 default:
176 break;
177 }
178
179 return 0;
180 }
181
182 int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
183 size_t size;
184 _cleanup_free_ DHCPPacket *discover;
185 uint16_t ip_check, udp_check;
186
187 assert_se(s >= 0);
188 assert_se(packet);
189
190 size = sizeof(DHCPPacket);
191 assert_se(len > size);
192
193 discover = memdup(packet, len);
194
195 assert_se(discover->ip.ttl == IPDEFTTL);
196 assert_se(discover->ip.protocol == IPPROTO_UDP);
197 assert_se(discover->ip.saddr == INADDR_ANY);
198 assert_se(discover->ip.daddr == INADDR_BROADCAST);
199 assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
200 assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
201
202 ip_check = discover->ip.check;
203
204 discover->ip.ttl = 0;
205 discover->ip.check = discover->udp.len;
206
207 udp_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip.ttl, len - 8);
208 assert_se(udp_check == 0xffff);
209
210 discover->ip.ttl = IPDEFTTL;
211 discover->ip.check = ip_check;
212
213 ip_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip, sizeof(discover->ip));
214 assert_se(ip_check == 0xffff);
215
216 assert_se(discover->dhcp.xid);
217 assert_se(memcmp(discover->dhcp.chaddr, &mac_addr, ETH_ALEN) == 0);
218
219 size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
220
221 assert_se(callback_recv);
222 callback_recv(size, &discover->dhcp);
223
224 return 575;
225 }
226
227 int dhcp_network_bind_raw_socket(
228 int index,
229 union sockaddr_union *link,
230 uint32_t id,
231 const uint8_t *addr, size_t addr_len,
232 uint16_t arp_type, uint16_t port) {
233
234 if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
235 return -errno;
236
237 return test_fd[0];
238 }
239
240 int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
241 int fd;
242
243 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
244 if (fd < 0)
245 return -errno;
246
247 return fd;
248 }
249
250 int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
251 return 0;
252 }
253
254 static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) {
255 int res;
256
257 res = dhcp_option_parse(dhcp, size, check_options, NULL, NULL);
258 assert_se(res == DHCP_DISCOVER);
259
260 if (verbose)
261 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
262
263 return 0;
264 }
265
266 static void test_discover_message(sd_event *e) {
267 sd_dhcp_client *client;
268 int res, r;
269
270 if (verbose)
271 printf("* %s\n", __FUNCTION__);
272
273 r = sd_dhcp_client_new(&client, false);
274 assert_se(r >= 0);
275 assert_se(client);
276
277 r = sd_dhcp_client_attach_event(client, e, 0);
278 assert_se(r >= 0);
279
280 assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
281 assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
282
283 assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
284
285 callback_recv = test_discover_message_verify;
286
287 res = sd_dhcp_client_start(client);
288
289 assert_se(IN_SET(res, 0, -EINPROGRESS));
290
291 sd_event_run(e, (uint64_t) -1);
292
293 sd_dhcp_client_stop(client);
294 sd_dhcp_client_unref(client);
295
296 test_fd[1] = safe_close(test_fd[1]);
297
298 callback_recv = NULL;
299 }
300
301 static uint8_t test_addr_acq_offer[] = {
302 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
303 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
304 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
305 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
306 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
308 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
336 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
337 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
338 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
339 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
340 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
341 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 };
344
345 static uint8_t test_addr_acq_ack[] = {
346 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
347 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
348 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
349 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
352 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
380 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
381 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
382 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
383 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
384 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
385 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 };
388
389 static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
390 void *userdata) {
391 sd_event *e = userdata;
392 sd_dhcp_lease *lease;
393 struct in_addr addr;
394
395 assert_se(client);
396 assert_se(event == SD_DHCP_CLIENT_EVENT_IP_ACQUIRE);
397
398 assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
399 assert_se(lease);
400
401 assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
402 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
403 sizeof(addr.s_addr)) == 0);
404
405 assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
406 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
407 sizeof(addr.s_addr)) == 0);
408
409 assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
410 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
411 sizeof(addr.s_addr)) == 0);
412
413 if (verbose)
414 printf(" DHCP address acquired\n");
415
416 sd_event_exit(e, 0);
417 }
418
419 static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
420 uint16_t udp_check = 0;
421 uint8_t *msg_bytes = (uint8_t *)request;
422 int res;
423
424 res = dhcp_option_parse(request, size, check_options, NULL, NULL);
425 assert_se(res == DHCP_REQUEST);
426 assert_se(xid == request->xid);
427
428 assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END);
429
430 if (verbose)
431 printf(" recv DHCP Request 0x%08x\n", be32toh(xid));
432
433 memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
434 memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
435 memcpy(&test_addr_acq_ack[56], &mac_addr, ETHER_ADDR_LEN);
436
437 callback_recv = NULL;
438
439 res = write(test_fd[1], test_addr_acq_ack,
440 sizeof(test_addr_acq_ack));
441 assert_se(res == sizeof(test_addr_acq_ack));
442
443 if (verbose)
444 printf(" send DHCP Ack\n");
445
446 return 0;
447 };
448
449 static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
450 uint16_t udp_check = 0;
451 uint8_t *msg_bytes = (uint8_t *)discover;
452 int res;
453
454 res = dhcp_option_parse(discover, size, check_options, NULL, NULL);
455 assert_se(res == DHCP_DISCOVER);
456
457 assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END);
458
459 xid = discover->xid;
460
461 if (verbose)
462 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid));
463
464 memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
465 memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
466 memcpy(&test_addr_acq_offer[56], &mac_addr, ETHER_ADDR_LEN);
467
468 callback_recv = test_addr_acq_recv_request;
469
470 res = write(test_fd[1], test_addr_acq_offer,
471 sizeof(test_addr_acq_offer));
472 assert_se(res == sizeof(test_addr_acq_offer));
473
474 if (verbose)
475 printf(" sent DHCP Offer\n");
476
477 return 0;
478 }
479
480 static void test_addr_acq(sd_event *e) {
481 usec_t time_now = now(clock_boottime_or_monotonic());
482 sd_dhcp_client *client;
483 int res, r;
484
485 if (verbose)
486 printf("* %s\n", __FUNCTION__);
487
488 r = sd_dhcp_client_new(&client, false);
489 assert_se(r >= 0);
490 assert_se(client);
491
492 r = sd_dhcp_client_attach_event(client, e, 0);
493 assert_se(r >= 0);
494
495 assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0);
496 assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
497
498 assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0);
499
500 callback_recv = test_addr_acq_recv_discover;
501
502 assert_se(sd_event_add_time(e, &test_hangcheck,
503 clock_boottime_or_monotonic(),
504 time_now + 2 * USEC_PER_SEC, 0,
505 test_dhcp_hangcheck, NULL) >= 0);
506
507 res = sd_dhcp_client_start(client);
508 assert_se(IN_SET(res, 0, -EINPROGRESS));
509
510 assert_se(sd_event_loop(e) >= 0);
511
512 test_hangcheck = sd_event_source_unref(test_hangcheck);
513
514 assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
515 assert_se(sd_dhcp_client_stop(client) >= 0);
516 sd_dhcp_client_unref(client);
517
518 test_fd[1] = safe_close(test_fd[1]);
519
520 callback_recv = NULL;
521 xid = 0;
522 }
523
524 int main(int argc, char *argv[]) {
525 _cleanup_(sd_event_unrefp) sd_event *e;
526
527 log_set_max_level(LOG_DEBUG);
528 log_parse_environment();
529 log_open();
530
531 assert_se(sd_event_new(&e) >= 0);
532
533 test_request_basic(e);
534 test_request_anonymize(e);
535 test_checksum();
536
537 test_discover_message(e);
538 test_addr_acq(e);
539
540 #if VALGRIND
541 /* Make sure the async_close thread has finished.
542 * valgrind would report some of the phread_* structures
543 * as not cleaned up properly. */
544 sleep(1);
545 #endif
546
547 return 0;
548 }