chiark / gitweb /
831ec190592985c5ed01e440dbc93c705a6d673e
[elogind.git] / src / libsystemd-network / test-dhcp-client.c
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>
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <unistd.h>
29
30 #include "util.h"
31 #include "socket-util.h"
32 #include "sd-event.h"
33 #include "event-util.h"
34
35 #include "dhcp-identifier.h"
36 #include "dhcp-protocol.h"
37 #include "dhcp-internal.h"
38 #include "sd-dhcp-client.h"
39
40 static uint8_t mac_addr[] = {'A', 'B', 'C', '1', '2', '3'};
41
42 typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
43
44 static bool verbose = true;
45 static int test_fd[2];
46 static test_callback_recv_t callback_recv;
47 static be32_t xid;
48 static sd_event_source *test_hangcheck;
49
50 static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
51                                void *userdata)
52 {
53         assert_not_reached("Test case should have completed in 2 seconds");
54
55         return 0;
56 }
57
58 static void test_request_basic(sd_event *e)
59 {
60         int r;
61
62         sd_dhcp_client *client;
63
64         if (verbose)
65                 printf("* %s\n", __FUNCTION__);
66
67         r = sd_dhcp_client_new(&client);
68
69         assert_se(r >= 0);
70         assert_se(client);
71
72         r = sd_dhcp_client_attach_event(client, e, 0);
73         assert_se(r >= 0);
74
75         assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
76         assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
77         assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
78
79         assert_se(sd_dhcp_client_set_index(client, 15) == 0);
80         assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
81         assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL);
82         assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL);
83         assert_se(sd_dhcp_client_set_index(client, 1) == 0);
84
85         assert_se(sd_dhcp_client_set_request_option(client,
86                                         DHCP_OPTION_SUBNET_MASK) == -EEXIST);
87         assert_se(sd_dhcp_client_set_request_option(client,
88                                         DHCP_OPTION_ROUTER) == -EEXIST);
89         assert_se(sd_dhcp_client_set_request_option(client,
90                                         DHCP_OPTION_HOST_NAME) == -EEXIST);
91         assert_se(sd_dhcp_client_set_request_option(client,
92                                         DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
93         assert_se(sd_dhcp_client_set_request_option(client,
94                                         DHCP_OPTION_DOMAIN_NAME_SERVER)
95                         == -EEXIST);
96         assert_se(sd_dhcp_client_set_request_option(client,
97                                         DHCP_OPTION_NTP_SERVER) == -EEXIST);
98
99         assert_se(sd_dhcp_client_set_request_option(client,
100                                         DHCP_OPTION_PAD) == -EINVAL);
101         assert_se(sd_dhcp_client_set_request_option(client,
102                                         DHCP_OPTION_END) == -EINVAL);
103         assert_se(sd_dhcp_client_set_request_option(client,
104                                         DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
105         assert_se(sd_dhcp_client_set_request_option(client,
106                                         DHCP_OPTION_OVERLOAD) == -EINVAL);
107         assert_se(sd_dhcp_client_set_request_option(client,
108                                         DHCP_OPTION_PARAMETER_REQUEST_LIST)
109                         == -EINVAL);
110
111         assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
112         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
113         assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
114         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
115
116         sd_dhcp_client_unref(client);
117 }
118
119 static void test_checksum(void)
120 {
121         uint8_t buf[20] = {
122                 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
123                 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124                 0xff, 0xff, 0xff, 0xff
125         };
126
127         if (verbose)
128                 printf("* %s\n", __FUNCTION__);
129
130         assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
131 }
132
133 static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
134                 void *user_data)
135 {
136         switch(code) {
137         case DHCP_OPTION_CLIENT_IDENTIFIER:
138         {
139                 uint32_t iaid;
140                 struct duid duid;
141                 size_t duid_len;
142
143                 assert_se(dhcp_identifier_set_duid_en(&duid, &duid_len) >= 0);
144                 assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, &iaid) >= 0);
145
146                 assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
147                 assert_se(len == 19);
148                 assert_se(option[0] == 0xff);
149
150                 assert_se(memcmp(&option[1], &iaid, sizeof(iaid)) == 0);
151                 assert_se(memcmp(&option[5], &duid, duid_len) == 0);
152                 break;
153         }
154
155         default:
156                 break;
157         }
158
159         return 0;
160 }
161
162 int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
163                                  const void *packet, size_t len)
164 {
165         size_t size;
166         _cleanup_free_ DHCPPacket *discover;
167         uint16_t ip_check, udp_check;
168
169         assert_se(s >= 0);
170         assert_se(packet);
171
172         size = sizeof(DHCPPacket);
173         assert_se(len > size);
174
175         discover = memdup(packet, len);
176
177         assert_se(discover->ip.ttl == IPDEFTTL);
178         assert_se(discover->ip.protocol == IPPROTO_UDP);
179         assert_se(discover->ip.saddr == INADDR_ANY);
180         assert_se(discover->ip.daddr == INADDR_BROADCAST);
181         assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
182         assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
183
184         ip_check = discover->ip.check;
185
186         discover->ip.ttl = 0;
187         discover->ip.check = discover->udp.len;
188
189         udp_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip.ttl, len - 8);
190         assert_se(udp_check == 0xffff);
191
192         discover->ip.ttl = IPDEFTTL;
193         discover->ip.check = ip_check;
194
195         ip_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip, sizeof(discover->ip));
196         assert_se(ip_check == 0xffff);
197
198         assert_se(discover->dhcp.xid);
199         assert_se(memcmp(discover->dhcp.chaddr, &mac_addr, ETH_ALEN) == 0);
200
201         size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
202
203         assert_se(callback_recv);
204         callback_recv(size, &discover->dhcp);
205
206         return 575;
207 }
208
209 int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
210                                  uint32_t id, const uint8_t *addr,
211                                  size_t addr_len, uint16_t arp_type)
212 {
213         if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
214                 return -errno;
215
216         return test_fd[0];
217 }
218
219 int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
220 {
221         int fd;
222
223         fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
224         if (fd < 0)
225                 return -errno;
226
227         return fd;
228 }
229
230 int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
231                                  const void *packet, size_t len)
232 {
233         return 0;
234 }
235
236 static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
237 {
238         int res;
239
240         res = dhcp_option_parse(dhcp, size, check_options, NULL);
241         assert_se(res == DHCP_DISCOVER);
242
243         if (verbose)
244                 printf("  recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
245
246         return 0;
247 }
248
249 static void test_discover_message(sd_event *e)
250 {
251         sd_dhcp_client *client;
252         int res, r;
253
254         if (verbose)
255                 printf("* %s\n", __FUNCTION__);
256
257         r = sd_dhcp_client_new(&client);
258         assert_se(r >= 0);
259         assert_se(client);
260
261         r = sd_dhcp_client_attach_event(client, e, 0);
262         assert_se(r >= 0);
263
264         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
265         assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
266
267         assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
268
269         callback_recv = test_discover_message_verify;
270
271         res = sd_dhcp_client_start(client);
272
273         assert_se(res == 0 || res == -EINPROGRESS);
274
275         sd_event_run(e, (uint64_t) -1);
276
277         sd_dhcp_client_stop(client);
278         sd_dhcp_client_unref(client);
279
280         test_fd[1] = safe_close(test_fd[1]);
281
282         callback_recv = NULL;
283 }
284
285 static uint8_t test_addr_acq_offer[] = {
286         0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
287         0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
288         0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
289         0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
290         0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
291         0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
292         0xc0, 0xa8, 0x02, 0x01, 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         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308         0x00, 0x00, 0x00, 0x00, 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         0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
320         0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
321         0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
322         0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
323         0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
324         0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
325         0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 };
328
329 static uint8_t test_addr_acq_ack[] = {
330         0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
331         0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
332         0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
333         0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
334         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
335         0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
336         0xc0, 0xa8, 0x02, 0x01, 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         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         0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
364         0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
365         0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
366         0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
367         0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
368         0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
369         0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 };
372
373 static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
374                                    void *userdata) {
375         sd_event *e = userdata;
376         sd_dhcp_lease *lease;
377         struct in_addr addr;
378
379         assert_se(client);
380         assert_se(event == DHCP_EVENT_IP_ACQUIRE);
381
382         assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
383         assert_se(lease);
384
385         assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
386         assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
387                       sizeof(addr.s_addr)) == 0);
388
389         assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
390         assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
391                       sizeof(addr.s_addr)) == 0);
392
393         assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
394         assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
395                       sizeof(addr.s_addr)) == 0);
396
397         if (verbose)
398                 printf("  DHCP address acquired\n");
399
400         sd_dhcp_lease_unref(lease);
401         sd_event_exit(e, 0);
402 }
403
404 static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
405         uint16_t udp_check = 0;
406         uint8_t *msg_bytes = (uint8_t *)request;
407         int res;
408
409         res = dhcp_option_parse(request, size, check_options, NULL);
410         assert_se(res == DHCP_REQUEST);
411         assert_se(xid == request->xid);
412
413         assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
414
415         if (verbose)
416                 printf("  recv DHCP Request  0x%08x\n", be32toh(xid));
417
418         memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
419         memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
420         memcpy(&test_addr_acq_ack[56], &mac_addr, ETHER_ADDR_LEN);
421
422         callback_recv = NULL;
423
424         res = write(test_fd[1], test_addr_acq_ack,
425                     sizeof(test_addr_acq_ack));
426         assert_se(res == sizeof(test_addr_acq_ack));
427
428         if (verbose)
429                 printf("  send DHCP Ack\n");
430
431         return 0;
432 };
433
434 static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
435         uint16_t udp_check = 0;
436         uint8_t *msg_bytes = (uint8_t *)discover;
437         int res;
438
439         res = dhcp_option_parse(discover, size, check_options, NULL);
440         assert_se(res == DHCP_DISCOVER);
441
442         assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
443
444         xid = discover->xid;
445
446         if (verbose)
447                 printf("  recv DHCP Discover 0x%08x\n", be32toh(xid));
448
449         memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
450         memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
451         memcpy(&test_addr_acq_offer[56], &mac_addr, ETHER_ADDR_LEN);
452
453         callback_recv = test_addr_acq_recv_request;
454
455         res = write(test_fd[1], test_addr_acq_offer,
456                     sizeof(test_addr_acq_offer));
457         assert_se(res == sizeof(test_addr_acq_offer));
458
459         if (verbose)
460                 printf("  sent DHCP Offer\n");
461
462         return 0;
463 }
464
465 static void test_addr_acq(sd_event *e) {
466         usec_t time_now = now(clock_boottime_or_monotonic());
467         sd_dhcp_client *client;
468         int res, r;
469
470         if (verbose)
471                 printf("* %s\n", __FUNCTION__);
472
473         r = sd_dhcp_client_new(&client);
474         assert_se(r >= 0);
475         assert_se(client);
476
477         r = sd_dhcp_client_attach_event(client, e, 0);
478         assert_se(r >= 0);
479
480         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
481         assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
482
483         assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0);
484
485         callback_recv = test_addr_acq_recv_discover;
486
487         assert_se(sd_event_add_time(e, &test_hangcheck,
488                                     clock_boottime_or_monotonic(),
489                                     time_now + 2 * USEC_PER_SEC, 0,
490                                     test_dhcp_hangcheck, NULL) >= 0);
491
492         res = sd_dhcp_client_start(client);
493         assert_se(res == 0 || res == -EINPROGRESS);
494
495         assert_se(sd_event_loop(e) >= 0);
496
497         test_hangcheck = sd_event_source_unref(test_hangcheck);
498
499         assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
500         assert_se(sd_dhcp_client_stop(client) >= 0);
501         sd_dhcp_client_unref(client);
502
503         test_fd[1] = safe_close(test_fd[1]);
504
505         callback_recv = NULL;
506         xid = 0;
507 }
508
509 int main(int argc, char *argv[]) {
510         _cleanup_event_unref_ sd_event *e;
511
512         log_set_max_level(LOG_DEBUG);
513         log_parse_environment();
514         log_open();
515
516         assert_se(sd_event_new(&e) >= 0);
517
518         test_request_basic(e);
519         test_checksum();
520
521         test_discover_message(e);
522         test_addr_acq(e);
523
524         return 0;
525 }