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