]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-dhcp-client.c
dhcp-identifier: create IAID even if no udev device can be found
[thirdparty/systemd.git] / src / libsystemd-network / test-dhcp-client.c
CommitLineData
be391925
PF
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright (C) 2013 Intel Corporation. All rights reserved.
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdlib.h>
23#include <assert.h>
24#include <errno.h>
39b7f596 25#include <stdio.h>
8c00042c
PF
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <unistd.h>
be391925 29
290c7324 30#include "util.h"
8c00042c 31#include "socket-util.h"
6e00a806
ZJS
32#include "sd-event.h"
33#include "event-util.h"
290c7324 34
be391925 35#include "dhcp-protocol.h"
290c7324 36#include "dhcp-internal.h"
be391925
PF
37#include "sd-dhcp-client.h"
38
290c7324
PF
39static struct ether_addr mac_addr = {
40 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
41};
42
6c8a0f07
PF
43typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
44
ede286f9 45static bool verbose = false;
8c00042c 46static int test_fd[2];
6c8a0f07 47static test_callback_recv_t callback_recv;
234ed3eb 48static be32_t xid;
8fc8e3ab
PF
49static sd_event_source *test_hangcheck;
50
51static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
52 void *userdata)
53{
54 assert_not_reached("Test case should have completed in 2 seconds");
55
56 return 0;
57}
8c00042c 58
d3d8ac2f 59static void test_request_basic(sd_event *e)
be391925 60{
b25ef18b
TG
61 int r;
62
be391925
PF
63 sd_dhcp_client *client;
64
ede286f9
PF
65 if (verbose)
66 printf("* %s\n", __FUNCTION__);
67
b25ef18b 68 r = sd_dhcp_client_new(&client);
be391925 69
12e0f830
TG
70 assert_se(r >= 0);
71 assert_se(client);
be391925 72
b25ef18b 73 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 74 assert_se(r >= 0);
b25ef18b 75
12e0f830
TG
76 assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
77 assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
78 assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
be391925 79
12e0f830
TG
80 assert_se(sd_dhcp_client_set_index(client, 15) == 0);
81 assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
d9bf4f8c
UTL
82 assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL);
83 assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL);
84 assert_se(sd_dhcp_client_set_index(client, 1) == 0);
be391925 85
12e0f830 86 assert_se(sd_dhcp_client_set_request_option(client,
be391925 87 DHCP_OPTION_SUBNET_MASK) == -EEXIST);
12e0f830 88 assert_se(sd_dhcp_client_set_request_option(client,
be391925 89 DHCP_OPTION_ROUTER) == -EEXIST);
12e0f830 90 assert_se(sd_dhcp_client_set_request_option(client,
be391925 91 DHCP_OPTION_HOST_NAME) == -EEXIST);
12e0f830 92 assert_se(sd_dhcp_client_set_request_option(client,
be391925 93 DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
12e0f830 94 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
95 DHCP_OPTION_DOMAIN_NAME_SERVER)
96 == -EEXIST);
12e0f830 97 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
98 DHCP_OPTION_NTP_SERVER) == -EEXIST);
99
12e0f830 100 assert_se(sd_dhcp_client_set_request_option(client,
be391925 101 DHCP_OPTION_PAD) == -EINVAL);
12e0f830 102 assert_se(sd_dhcp_client_set_request_option(client,
be391925 103 DHCP_OPTION_END) == -EINVAL);
12e0f830 104 assert_se(sd_dhcp_client_set_request_option(client,
be391925 105 DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
12e0f830 106 assert_se(sd_dhcp_client_set_request_option(client,
be391925 107 DHCP_OPTION_OVERLOAD) == -EINVAL);
12e0f830 108 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
109 DHCP_OPTION_PARAMETER_REQUEST_LIST)
110 == -EINVAL);
111
12e0f830
TG
112 assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
113 assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
114 assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
115 assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
6e00a806
ZJS
116
117 sd_dhcp_client_unref(client);
be391925
PF
118}
119
39b7f596
PF
120static void test_checksum(void)
121{
122 uint8_t buf[20] = {
123 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
124 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0xff, 0xff, 0xff, 0xff
126 };
127
ede286f9
PF
128 if (verbose)
129 printf("* %s\n", __FUNCTION__);
130
0bbc2c1f 131 assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
39b7f596
PF
132}
133
290c7324
PF
134static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
135 void *user_data)
136{
d790d3f1
PF
137 switch(code) {
138 case DHCP_OPTION_CLIENT_IDENTIFIER:
139 assert_se(len == 7);
140 assert_se(option[0] == 0x01);
141 assert_se(memcmp(&option[1], &mac_addr, ETH_ALEN) == 0);
142 break;
143
144 default:
145 break;
146 }
147
290c7324
PF
148 return 0;
149}
150
8c00042c
PF
151int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
152 const void *packet, size_t len)
290c7324
PF
153{
154 size_t size;
f937d3d6 155 _cleanup_free_ DHCPPacket *discover;
290c7324 156 uint16_t ip_check, udp_check;
290c7324 157
12e0f830
TG
158 assert_se(s >= 0);
159 assert_se(packet);
290c7324 160
d47e1de4 161 size = sizeof(DHCPPacket);
12e0f830 162 assert_se(len > size);
290c7324
PF
163
164 discover = memdup(packet, len);
165
12e0f830
TG
166 assert_se(discover->ip.ttl == IPDEFTTL);
167 assert_se(discover->ip.protocol == IPPROTO_UDP);
168 assert_se(discover->ip.saddr == INADDR_ANY);
169 assert_se(discover->ip.daddr == INADDR_BROADCAST);
170 assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
171 assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
290c7324
PF
172
173 ip_check = discover->ip.check;
174
175 discover->ip.ttl = 0;
176 discover->ip.check = discover->udp.len;
177
0bbc2c1f 178 udp_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip.ttl, len - 8);
12e0f830 179 assert_se(udp_check == 0xffff);
290c7324
PF
180
181 discover->ip.ttl = IPDEFTTL;
182 discover->ip.check = ip_check;
183
0bbc2c1f 184 ip_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip, sizeof(discover->ip));
12e0f830 185 assert_se(ip_check == 0xffff);
290c7324 186
12e0f830
TG
187 assert_se(discover->dhcp.xid);
188 assert_se(memcmp(discover->dhcp.chaddr,
6c8a0f07
PF
189 &mac_addr.ether_addr_octet, 6) == 0);
190
290c7324
PF
191 size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
192
12e0f830 193 assert_se(callback_recv);
6c8a0f07 194 callback_recv(size, &discover->dhcp);
290c7324
PF
195
196 return 575;
197}
198
76253e73
DW
199int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
200 uint32_t id, const uint8_t *addr,
201 size_t addr_len, uint16_t arp_type)
8c00042c
PF
202{
203 if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
204 return -errno;
205
206 return test_fd[0];
207}
208
085cabf2 209int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
234fc2df
PF
210{
211 return 0;
212}
213
080ab276 214int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
234fc2df
PF
215 const void *packet, size_t len)
216{
217 return 0;
218}
219
6c8a0f07
PF
220static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
221{
222 int res;
223
224 res = dhcp_option_parse(dhcp, size, check_options, NULL);
12e0f830 225 assert_se(res == DHCP_DISCOVER);
6c8a0f07
PF
226
227 if (verbose)
228 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
229
230 return 0;
231}
232
d3d8ac2f 233static void test_discover_message(sd_event *e)
290c7324
PF
234{
235 sd_dhcp_client *client;
b25ef18b 236 int res, r;
290c7324 237
ede286f9
PF
238 if (verbose)
239 printf("* %s\n", __FUNCTION__);
240
b25ef18b 241 r = sd_dhcp_client_new(&client);
12e0f830
TG
242 assert_se(r >= 0);
243 assert_se(client);
290c7324 244
b25ef18b 245 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 246 assert_se(r >= 0);
b25ef18b 247
12e0f830 248 assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
76253e73
DW
249 assert_se(sd_dhcp_client_set_mac(client,
250 (const uint8_t *) &mac_addr,
251 sizeof (mac_addr),
252 ARPHRD_ETHER) >= 0);
290c7324 253
12e0f830 254 assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
290c7324 255
6c8a0f07
PF
256 callback_recv = test_discover_message_verify;
257
290c7324
PF
258 res = sd_dhcp_client_start(client);
259
12e0f830 260 assert_se(res == 0 || res == -EINPROGRESS);
8c00042c 261
6c8a0f07
PF
262 sd_event_run(e, (uint64_t) -1);
263
264 sd_dhcp_client_stop(client);
e5b04c8d 265 sd_dhcp_client_unref(client);
6c8a0f07 266
2afa65c3 267 test_fd[1] = safe_close(test_fd[1]);
6c8a0f07
PF
268
269 callback_recv = NULL;
290c7324
PF
270}
271
234ed3eb
PF
272static uint8_t test_addr_acq_offer[] = {
273 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
274 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
275 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
276 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
277 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
279 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
307 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
308 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
309 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
310 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
311 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
312 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314};
315
316static uint8_t test_addr_acq_ack[] = {
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 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, 0x05, 0x36,
351 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
d47e1de4 352 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
234ed3eb
PF
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,
358};
359
360static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
c4acff12 361 void *userdata) {
234ed3eb
PF
362 sd_event *e = userdata;
363 sd_dhcp_lease *lease;
364 struct in_addr addr;
365
12e0f830
TG
366 assert_se(client);
367 assert_se(event == DHCP_EVENT_IP_ACQUIRE);
234ed3eb 368
12e0f830
TG
369 assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
370 assert_se(lease);
234ed3eb 371
12e0f830
TG
372 assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
373 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
234ed3eb
PF
374 sizeof(addr.s_addr)) == 0);
375
12e0f830
TG
376 assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
377 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
234ed3eb
PF
378 sizeof(addr.s_addr)) == 0);
379
12e0f830
TG
380 assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
381 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
234ed3eb
PF
382 sizeof(addr.s_addr)) == 0);
383
384 if (verbose)
385 printf(" DHCP address acquired\n");
386
6e00a806 387 sd_dhcp_lease_unref(lease);
234ed3eb
PF
388 sd_event_exit(e, 0);
389}
390
c4acff12 391static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
234ed3eb 392 uint16_t udp_check = 0;
d790d3f1 393 uint8_t *msg_bytes = (uint8_t *)request;
234ed3eb
PF
394 int res;
395
396 res = dhcp_option_parse(request, size, check_options, NULL);
12e0f830
TG
397 assert_se(res == DHCP_REQUEST);
398 assert_se(xid == request->xid);
234ed3eb 399
d790d3f1
PF
400 assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
401
234ed3eb
PF
402 if (verbose)
403 printf(" recv DHCP Request 0x%08x\n", be32toh(xid));
404
405 memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
406 memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
407 memcpy(&test_addr_acq_ack[56], &mac_addr.ether_addr_octet,
408 ETHER_ADDR_LEN);
409
410 callback_recv = NULL;
411
412 res = write(test_fd[1], test_addr_acq_ack,
413 sizeof(test_addr_acq_ack));
12e0f830 414 assert_se(res == sizeof(test_addr_acq_ack));
234ed3eb
PF
415
416 if (verbose)
417 printf(" send DHCP Ack\n");
418
419 return 0;
420};
421
c4acff12 422static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
234ed3eb 423 uint16_t udp_check = 0;
d790d3f1 424 uint8_t *msg_bytes = (uint8_t *)discover;
234ed3eb
PF
425 int res;
426
427 res = dhcp_option_parse(discover, size, check_options, NULL);
12e0f830 428 assert_se(res == DHCP_DISCOVER);
234ed3eb 429
d790d3f1
PF
430 assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
431
234ed3eb
PF
432 xid = discover->xid;
433
434 if (verbose)
435 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid));
436
437 memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
438 memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
439 memcpy(&test_addr_acq_offer[56], &mac_addr.ether_addr_octet,
440 ETHER_ADDR_LEN);
441
442 callback_recv = test_addr_acq_recv_request;
443
444 res = write(test_fd[1], test_addr_acq_offer,
445 sizeof(test_addr_acq_offer));
12e0f830 446 assert_se(res == sizeof(test_addr_acq_offer));
234ed3eb
PF
447
448 if (verbose)
c4acff12 449 printf(" sent DHCP Offer\n");
234ed3eb
PF
450
451 return 0;
452}
453
c4acff12 454static void test_addr_acq(sd_event *e) {
fa94c34b 455 usec_t time_now = now(clock_boottime_or_monotonic());
234ed3eb
PF
456 sd_dhcp_client *client;
457 int res, r;
458
459 if (verbose)
460 printf("* %s\n", __FUNCTION__);
461
462 r = sd_dhcp_client_new(&client);
12e0f830
TG
463 assert_se(r >= 0);
464 assert_se(client);
234ed3eb
PF
465
466 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 467 assert_se(r >= 0);
234ed3eb 468
12e0f830 469 assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
76253e73
DW
470 assert_se(sd_dhcp_client_set_mac(client,
471 (const uint8_t *) &mac_addr,
472 sizeof (mac_addr),
473 ARPHRD_ETHER) >= 0);
234ed3eb 474
12e0f830 475 assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
234ed3eb
PF
476 >= 0);
477
478 callback_recv = test_addr_acq_recv_discover;
479
6a0f1f6d 480 assert_se(sd_event_add_time(e, &test_hangcheck,
fa94c34b 481 clock_boottime_or_monotonic(),
6a0f1f6d
LP
482 time_now + 2 * USEC_PER_SEC, 0,
483 test_dhcp_hangcheck, NULL) >= 0);
8fc8e3ab 484
234ed3eb 485 res = sd_dhcp_client_start(client);
12e0f830 486 assert_se(res == 0 || res == -EINPROGRESS);
234ed3eb 487
fc292b5f 488 assert_se(sd_event_loop(e) >= 0);
234ed3eb 489
8fc8e3ab
PF
490 test_hangcheck = sd_event_source_unref(test_hangcheck);
491
fc292b5f
TG
492 assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
493 assert_se(sd_dhcp_client_stop(client) >= 0);
e5b04c8d 494 sd_dhcp_client_unref(client);
234ed3eb 495
2afa65c3 496 test_fd[1] = safe_close(test_fd[1]);
234ed3eb
PF
497
498 callback_recv = NULL;
499 xid = 0;
500}
501
c4acff12 502int main(int argc, char *argv[]) {
6e00a806
ZJS
503 _cleanup_event_unref_ sd_event *e;
504
505 log_set_max_level(LOG_DEBUG);
506 log_parse_environment();
507 log_open();
d3d8ac2f 508
12e0f830 509 assert_se(sd_event_new(&e) >= 0);
d3d8ac2f
PF
510
511 test_request_basic(e);
39b7f596 512 test_checksum();
be391925 513
d3d8ac2f 514 test_discover_message(e);
234ed3eb 515 test_addr_acq(e);
290c7324 516
be391925
PF
517 return 0;
518}