]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-dhcp-client.c
Unify GREEDY_REALLOC and GREEDY_REALLOC_T
[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"
290c7324 32
be391925 33#include "dhcp-protocol.h"
290c7324 34#include "dhcp-internal.h"
be391925
PF
35#include "sd-dhcp-client.h"
36
290c7324
PF
37static struct ether_addr mac_addr = {
38 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
39};
40
6c8a0f07
PF
41typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
42
ede286f9 43static bool verbose = false;
8c00042c 44static int test_fd[2];
6c8a0f07 45static test_callback_recv_t callback_recv;
234ed3eb 46static be32_t xid;
8fc8e3ab
PF
47static sd_event_source *test_hangcheck;
48
49static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
50 void *userdata)
51{
52 assert_not_reached("Test case should have completed in 2 seconds");
53
54 return 0;
55}
8c00042c 56
d3d8ac2f 57static void test_request_basic(sd_event *e)
be391925 58{
b25ef18b
TG
59 int r;
60
be391925
PF
61 sd_dhcp_client *client;
62
ede286f9
PF
63 if (verbose)
64 printf("* %s\n", __FUNCTION__);
65
b25ef18b 66 r = sd_dhcp_client_new(&client);
be391925 67
12e0f830
TG
68 assert_se(r >= 0);
69 assert_se(client);
be391925 70
b25ef18b 71 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 72 assert_se(r >= 0);
b25ef18b 73
12e0f830
TG
74 assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
75 assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
76 assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
be391925 77
12e0f830
TG
78 assert_se(sd_dhcp_client_set_index(client, 15) == 0);
79 assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
80 assert_se(sd_dhcp_client_set_index(client, -1) == 0);
be391925 81
12e0f830 82 assert_se(sd_dhcp_client_set_request_option(client,
be391925 83 DHCP_OPTION_SUBNET_MASK) == -EEXIST);
12e0f830 84 assert_se(sd_dhcp_client_set_request_option(client,
be391925 85 DHCP_OPTION_ROUTER) == -EEXIST);
12e0f830 86 assert_se(sd_dhcp_client_set_request_option(client,
be391925 87 DHCP_OPTION_HOST_NAME) == -EEXIST);
12e0f830 88 assert_se(sd_dhcp_client_set_request_option(client,
be391925 89 DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
12e0f830 90 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
91 DHCP_OPTION_DOMAIN_NAME_SERVER)
92 == -EEXIST);
12e0f830 93 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
94 DHCP_OPTION_NTP_SERVER) == -EEXIST);
95
12e0f830 96 assert_se(sd_dhcp_client_set_request_option(client,
be391925 97 DHCP_OPTION_PAD) == -EINVAL);
12e0f830 98 assert_se(sd_dhcp_client_set_request_option(client,
be391925 99 DHCP_OPTION_END) == -EINVAL);
12e0f830 100 assert_se(sd_dhcp_client_set_request_option(client,
be391925 101 DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
12e0f830 102 assert_se(sd_dhcp_client_set_request_option(client,
be391925 103 DHCP_OPTION_OVERLOAD) == -EINVAL);
12e0f830 104 assert_se(sd_dhcp_client_set_request_option(client,
be391925
PF
105 DHCP_OPTION_PARAMETER_REQUEST_LIST)
106 == -EINVAL);
107
12e0f830
TG
108 assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
109 assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
110 assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
111 assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
be391925
PF
112}
113
39b7f596
PF
114static void test_checksum(void)
115{
116 uint8_t buf[20] = {
117 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
118 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0xff, 0xff, 0xff, 0xff
120 };
121
ede286f9
PF
122 if (verbose)
123 printf("* %s\n", __FUNCTION__);
124
a838c939 125 assert_se(dhcp_packet_checksum(&buf, 20) == be16toh(0x78ae));
39b7f596
PF
126}
127
290c7324
PF
128static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
129 void *user_data)
130{
d790d3f1
PF
131 switch(code) {
132 case DHCP_OPTION_CLIENT_IDENTIFIER:
133 assert_se(len == 7);
134 assert_se(option[0] == 0x01);
135 assert_se(memcmp(&option[1], &mac_addr, ETH_ALEN) == 0);
136 break;
137
138 default:
139 break;
140 }
141
290c7324
PF
142 return 0;
143}
144
8c00042c
PF
145int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
146 const void *packet, size_t len)
290c7324
PF
147{
148 size_t size;
f937d3d6 149 _cleanup_free_ DHCPPacket *discover;
290c7324 150 uint16_t ip_check, udp_check;
290c7324 151
12e0f830
TG
152 assert_se(s >= 0);
153 assert_se(packet);
290c7324 154
d47e1de4 155 size = sizeof(DHCPPacket);
12e0f830 156 assert_se(len > size);
290c7324
PF
157
158 discover = memdup(packet, len);
159
12e0f830
TG
160 assert_se(discover->ip.ttl == IPDEFTTL);
161 assert_se(discover->ip.protocol == IPPROTO_UDP);
162 assert_se(discover->ip.saddr == INADDR_ANY);
163 assert_se(discover->ip.daddr == INADDR_BROADCAST);
164 assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
165 assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
290c7324
PF
166
167 ip_check = discover->ip.check;
168
169 discover->ip.ttl = 0;
170 discover->ip.check = discover->udp.len;
171
a838c939 172 udp_check = ~dhcp_packet_checksum(&discover->ip.ttl, len - 8);
12e0f830 173 assert_se(udp_check == 0xffff);
290c7324
PF
174
175 discover->ip.ttl = IPDEFTTL;
176 discover->ip.check = ip_check;
177
a838c939 178 ip_check = ~dhcp_packet_checksum(&discover->ip, sizeof(discover->ip));
12e0f830 179 assert_se(ip_check == 0xffff);
290c7324 180
12e0f830
TG
181 assert_se(discover->dhcp.xid);
182 assert_se(memcmp(discover->dhcp.chaddr,
6c8a0f07
PF
183 &mac_addr.ether_addr_octet, 6) == 0);
184
290c7324
PF
185 size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
186
12e0f830 187 assert_se(callback_recv);
6c8a0f07 188 callback_recv(size, &discover->dhcp);
290c7324
PF
189
190 return 575;
191}
192
7429b07f 193int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t id)
8c00042c
PF
194{
195 if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
196 return -errno;
197
198 return test_fd[0];
199}
200
080ab276 201int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port)
234fc2df
PF
202{
203 return 0;
204}
205
080ab276 206int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
234fc2df
PF
207 const void *packet, size_t len)
208{
209 return 0;
210}
211
6c8a0f07
PF
212static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
213{
214 int res;
215
216 res = dhcp_option_parse(dhcp, size, check_options, NULL);
12e0f830 217 assert_se(res == DHCP_DISCOVER);
6c8a0f07
PF
218
219 if (verbose)
220 printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
221
222 return 0;
223}
224
d3d8ac2f 225static void test_discover_message(sd_event *e)
290c7324
PF
226{
227 sd_dhcp_client *client;
b25ef18b 228 int res, r;
290c7324 229
ede286f9
PF
230 if (verbose)
231 printf("* %s\n", __FUNCTION__);
232
b25ef18b 233 r = sd_dhcp_client_new(&client);
12e0f830
TG
234 assert_se(r >= 0);
235 assert_se(client);
290c7324 236
b25ef18b 237 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 238 assert_se(r >= 0);
b25ef18b 239
12e0f830
TG
240 assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
241 assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
290c7324 242
12e0f830 243 assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
290c7324 244
6c8a0f07
PF
245 callback_recv = test_discover_message_verify;
246
290c7324
PF
247 res = sd_dhcp_client_start(client);
248
12e0f830 249 assert_se(res == 0 || res == -EINPROGRESS);
8c00042c 250
6c8a0f07
PF
251 sd_event_run(e, (uint64_t) -1);
252
253 sd_dhcp_client_stop(client);
e5b04c8d 254 sd_dhcp_client_unref(client);
6c8a0f07 255
2afa65c3 256 test_fd[1] = safe_close(test_fd[1]);
6c8a0f07
PF
257
258 callback_recv = NULL;
290c7324
PF
259}
260
234ed3eb
PF
261static uint8_t test_addr_acq_offer[] = {
262 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
263 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
264 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
265 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
266 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
268 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
296 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
297 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
298 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
299 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
300 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
301 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303};
304
305static uint8_t test_addr_acq_ack[] = {
306 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
307 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
308 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
309 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
312 0xc0, 0xa8, 0x02, 0x01, 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 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 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
340 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
d47e1de4 341 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
234ed3eb
PF
342 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
343 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
344 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
345 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347};
348
349static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
c4acff12 350 void *userdata) {
234ed3eb
PF
351 sd_event *e = userdata;
352 sd_dhcp_lease *lease;
353 struct in_addr addr;
354
12e0f830
TG
355 assert_se(client);
356 assert_se(event == DHCP_EVENT_IP_ACQUIRE);
234ed3eb 357
12e0f830
TG
358 assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
359 assert_se(lease);
234ed3eb 360
12e0f830
TG
361 assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
362 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
234ed3eb
PF
363 sizeof(addr.s_addr)) == 0);
364
12e0f830
TG
365 assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
366 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
234ed3eb
PF
367 sizeof(addr.s_addr)) == 0);
368
12e0f830
TG
369 assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
370 assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
234ed3eb
PF
371 sizeof(addr.s_addr)) == 0);
372
373 if (verbose)
374 printf(" DHCP address acquired\n");
375
376 sd_event_exit(e, 0);
377}
378
c4acff12 379static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
234ed3eb 380 uint16_t udp_check = 0;
d790d3f1 381 uint8_t *msg_bytes = (uint8_t *)request;
234ed3eb
PF
382 int res;
383
384 res = dhcp_option_parse(request, size, check_options, NULL);
12e0f830
TG
385 assert_se(res == DHCP_REQUEST);
386 assert_se(xid == request->xid);
234ed3eb 387
d790d3f1
PF
388 assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
389
234ed3eb
PF
390 if (verbose)
391 printf(" recv DHCP Request 0x%08x\n", be32toh(xid));
392
393 memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
394 memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
395 memcpy(&test_addr_acq_ack[56], &mac_addr.ether_addr_octet,
396 ETHER_ADDR_LEN);
397
398 callback_recv = NULL;
399
400 res = write(test_fd[1], test_addr_acq_ack,
401 sizeof(test_addr_acq_ack));
12e0f830 402 assert_se(res == sizeof(test_addr_acq_ack));
234ed3eb
PF
403
404 if (verbose)
405 printf(" send DHCP Ack\n");
406
407 return 0;
408};
409
c4acff12 410static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
234ed3eb 411 uint16_t udp_check = 0;
d790d3f1 412 uint8_t *msg_bytes = (uint8_t *)discover;
234ed3eb
PF
413 int res;
414
415 res = dhcp_option_parse(discover, size, check_options, NULL);
12e0f830 416 assert_se(res == DHCP_DISCOVER);
234ed3eb 417
d790d3f1
PF
418 assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
419
234ed3eb
PF
420 xid = discover->xid;
421
422 if (verbose)
423 printf(" recv DHCP Discover 0x%08x\n", be32toh(xid));
424
425 memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
426 memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
427 memcpy(&test_addr_acq_offer[56], &mac_addr.ether_addr_octet,
428 ETHER_ADDR_LEN);
429
430 callback_recv = test_addr_acq_recv_request;
431
432 res = write(test_fd[1], test_addr_acq_offer,
433 sizeof(test_addr_acq_offer));
12e0f830 434 assert_se(res == sizeof(test_addr_acq_offer));
234ed3eb
PF
435
436 if (verbose)
c4acff12 437 printf(" sent DHCP Offer\n");
234ed3eb
PF
438
439 return 0;
440}
441
c4acff12 442static void test_addr_acq(sd_event *e) {
8fc8e3ab 443 usec_t time_now = now(CLOCK_MONOTONIC);
234ed3eb
PF
444 sd_dhcp_client *client;
445 int res, r;
446
447 if (verbose)
448 printf("* %s\n", __FUNCTION__);
449
450 r = sd_dhcp_client_new(&client);
12e0f830
TG
451 assert_se(r >= 0);
452 assert_se(client);
234ed3eb
PF
453
454 r = sd_dhcp_client_attach_event(client, e, 0);
12e0f830 455 assert_se(r >= 0);
234ed3eb 456
12e0f830
TG
457 assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
458 assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
234ed3eb 459
12e0f830 460 assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
234ed3eb
PF
461 >= 0);
462
463 callback_recv = test_addr_acq_recv_discover;
464
6a0f1f6d
LP
465 assert_se(sd_event_add_time(e, &test_hangcheck,
466 CLOCK_MONOTONIC,
467 time_now + 2 * USEC_PER_SEC, 0,
468 test_dhcp_hangcheck, NULL) >= 0);
8fc8e3ab 469
234ed3eb 470 res = sd_dhcp_client_start(client);
12e0f830 471 assert_se(res == 0 || res == -EINPROGRESS);
234ed3eb
PF
472
473 sd_event_loop(e);
474
8fc8e3ab
PF
475 test_hangcheck = sd_event_source_unref(test_hangcheck);
476
234ed3eb
PF
477 sd_dhcp_client_set_callback(client, NULL, NULL);
478 sd_dhcp_client_stop(client);
e5b04c8d 479 sd_dhcp_client_unref(client);
234ed3eb 480
2afa65c3 481 test_fd[1] = safe_close(test_fd[1]);
234ed3eb
PF
482
483 callback_recv = NULL;
484 xid = 0;
485}
486
c4acff12 487int main(int argc, char *argv[]) {
d3d8ac2f
PF
488 sd_event *e;
489
12e0f830 490 assert_se(sd_event_new(&e) >= 0);
d3d8ac2f
PF
491
492 test_request_basic(e);
39b7f596 493 test_checksum();
be391925 494
d3d8ac2f 495 test_discover_message(e);
234ed3eb 496 test_addr_acq(e);
290c7324 497
be391925
PF
498 return 0;
499}