chiark / gitweb /
sd-dhcp6-client: Add Option Request Option support
[elogind.git] / src / libsystemd-network / test-dhcp6-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) 2014 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 <stdbool.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27 #include <net/ethernet.h>
28
29 #include "socket-util.h"
30 #include "macro.h"
31 #include "sd-event.h"
32 #include "event-util.h"
33 #include "virt.h"
34
35 #include "sd-dhcp6-client.h"
36 #include "dhcp6-protocol.h"
37 #include "dhcp6-internal.h"
38 #include "dhcp6-lease-internal.h"
39
40 static struct ether_addr mac_addr = {
41         .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
42 };
43
44 static bool verbose = false;
45
46 static sd_event_source *hangcheck;
47 static int test_dhcp_fd[2];
48 static int test_index = 42;
49 static int test_client_message_num;
50 static be32_t test_iaid = 0;
51 static uint8_t test_duid[14] = { };
52
53 static int test_client_basic(sd_event *e) {
54         sd_dhcp6_client *client;
55
56         if (verbose)
57                 printf("* %s\n", __FUNCTION__);
58
59         assert_se(sd_dhcp6_client_new(&client) >= 0);
60         assert_se(client);
61
62         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
63
64         assert_se(sd_dhcp6_client_set_index(client, 15) == 0);
65         assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL);
66         assert_se(sd_dhcp6_client_set_index(client, -1) == 0);
67         assert_se(sd_dhcp6_client_set_index(client, 42) >= 0);
68
69         assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
70
71         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL);
72         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
73         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_NTP_SERVER) == -EEXIST);
74         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_SNTP_SERVERS) == 0);
75         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
76         assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
77
78         assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
79
80         assert_se(sd_dhcp6_client_detach_event(client) >= 0);
81         assert_se(!sd_dhcp6_client_unref(client));
82
83         return 0;
84 }
85
86 static int test_option(sd_event *e) {
87         uint8_t packet[] = {
88                 'F', 'O', 'O',
89                 0x00, DHCP6_OPTION_ORO, 0x00, 0x07,
90                 'A', 'B', 'C', 'D', 'E', 'F', 'G',
91                 0x00, DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
92                 '1', '2', '3', '4', '5', '6', '7', '8', '9',
93                 'B', 'A', 'R',
94         };
95         uint8_t result[] = {
96                 'F', 'O', 'O',
97                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100                 'B', 'A', 'R',
101         };
102         uint16_t optcode;
103         size_t optlen;
104         uint8_t *optval, *buf, *out;
105         size_t zero = 0, pos = 3;
106         size_t buflen = sizeof(packet), outlen = sizeof(result);
107
108         if (verbose)
109                 printf("* %s\n", __FUNCTION__);
110
111         assert_se(buflen == outlen);
112
113         assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
114                                      &optval) == -ENOMSG);
115
116         buflen -= 3;
117         buf = &packet[3];
118         outlen -= 3;
119         out = &result[3];
120
121         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
122                                      &optval) >= 0);
123         pos += 4 + optlen;
124         assert_se(buf == &packet[pos]);
125         assert_se(optcode == DHCP6_OPTION_ORO);
126         assert_se(optlen == 7);
127         assert_se(buflen + pos == sizeof(packet));
128
129         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
130                                       optval) >= 0);
131         assert_se(out == &result[pos]);
132         assert_se(*out == 0x00);
133
134         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
135                                      &optval) >= 0);
136         pos += 4 + optlen;
137         assert_se(buf == &packet[pos]);
138         assert_se(optcode == DHCP6_OPTION_VENDOR_CLASS);
139         assert_se(optlen == 9);
140         assert_se(buflen + pos == sizeof(packet));
141
142         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
143                                       optval) >= 0);
144         assert_se(out == &result[pos]);
145         assert_se(*out == 'B');
146
147         assert_se(memcmp(packet, result, sizeof(packet)) == 0);
148
149         return 0;
150 }
151
152 static uint8_t msg_advertise[198] = {
153         0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
154         0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
155         0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
156         0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
157         0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
158         0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
159         0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
160         0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
161         0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
162         0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
163         0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
164         0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
165         0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
166         0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
167         0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
168         0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
169         0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
170         0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
171         0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
172         0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
173         0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
174         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
175         0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
176         0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
177         0x53, 0x00, 0x07, 0x00, 0x01, 0x00
178 };
179
180 static uint8_t msg_reply[173] = {
181         0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
182         0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
183         0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
184         0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
185         0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
186         0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
187         0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
188         0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
189         0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
190         0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
191         0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
192         0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
193         0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
194         0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
195         0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
196         0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
197         0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198         0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
199         0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
200         0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
201         0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
202         0x00, 0x00, 0x00, 0x00, 0x01
203 };
204
205 static int test_advertise_option(sd_event *e) {
206         _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
207         DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
208         uint8_t *optval, *opt = &msg_advertise[sizeof(DHCP6Message)];
209         uint16_t optcode;
210         size_t optlen, len = sizeof(msg_advertise);
211         be32_t val;
212         uint8_t preference = 255;
213         struct in6_addr addr;
214         uint32_t lt_pref, lt_valid;
215         int r;
216         bool opt_clientid = false;
217
218         if (verbose)
219                 printf("* %s\n", __FUNCTION__);
220
221         assert_se(dhcp6_lease_new(&lease) >= 0);
222
223         assert_se(advertise->type == DHCP6_ADVERTISE);
224         assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
225                   0x0fb4e5);
226
227         while ((r = dhcp6_option_parse(&opt, &len, &optcode, &optlen,
228                                        &optval)) >= 0) {
229
230                 switch(optcode) {
231                 case DHCP6_OPTION_CLIENTID:
232                         assert_se(optlen == 14);
233
234                         opt_clientid = true;
235                         break;
236
237                 case DHCP6_OPTION_IA_NA:
238                         assert_se(optlen == 94);
239                         assert_se(!memcmp(optval, &msg_advertise[26], optlen));
240
241                         val = htobe32(0x0ecfa37d);
242                         assert_se(!memcmp(optval, &val, sizeof(val)));
243
244                         val = htobe32(80);
245                         assert_se(!memcmp(optval + 4, &val, sizeof(val)));
246
247                         val = htobe32(120);
248                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
249
250                         assert_se(dhcp6_option_parse_ia(&optval, &optlen,
251                                                         optcode,
252                                                         &lease->ia) >= 0);
253
254                         break;
255
256                 case DHCP6_OPTION_SERVERID:
257                         assert_se(optlen == 14);
258                         assert_se(!memcmp(optval, &msg_advertise[179], optlen));
259
260                         assert_se(dhcp6_lease_set_serverid(lease, optval,
261                                                            optlen) >= 0);
262                         break;
263
264                 case DHCP6_OPTION_PREFERENCE:
265                         assert_se(optlen == 1);
266                         assert_se(!*optval);
267
268                         assert_se(dhcp6_lease_set_preference(lease,
269                                                              *optval) >= 0);
270                         break;
271
272                 default:
273                         break;
274                 }
275         }
276
277
278         assert_se(r == -ENOMSG);
279
280         assert_se(opt_clientid);
281
282         assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
283                                                    &lt_valid) >= 0);
284         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
285         assert_se(lt_pref == 150);
286         assert_se(lt_valid == 180);
287         assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
288                                                   &lt_valid) == -ENOMSG);
289
290         assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
291                                                    &lt_valid) >= 0);
292         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
293         assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
294                                                   &lt_valid) == -ENOMSG);
295         assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
296                                                   &lt_valid) == -ENOMSG);
297         assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
298                                                    &lt_valid) >= 0);
299         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
300         assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
301                                                   &lt_valid) == -ENOMSG);
302
303         assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
304         assert_se(len == 14);
305         assert_se(!memcmp(opt, &msg_advertise[179], len));
306
307         assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
308         assert_se(preference == 0);
309
310         return 0;
311 }
312
313 static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
314         assert_not_reached("Test case should have completed in 2 seconds");
315
316         return 0;
317 }
318
319 int detect_vm(const char **id) {
320         return 1;
321 }
322
323 int detect_container(const char **id) {
324         return 1;
325 }
326
327 int detect_virtualization(const char **id) {
328         return 1;
329 }
330
331 int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
332         assert_se(index == test_index);
333
334         if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0)
335                 return -errno;
336
337         return test_dhcp_fd[0];
338 }
339
340 static int test_client_send_reply(DHCP6Message *request) {
341         DHCP6Message reply;
342
343         reply.transaction_id = request->transaction_id;
344         reply.type = DHCP6_REPLY;
345
346         memcpy(msg_reply, &reply.transaction_id, 4);
347
348         memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
349
350         memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
351
352         assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
353                   == sizeof(msg_reply));
354
355         return 0;
356 }
357
358 static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
359                                       size_t len) {
360         _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
361         uint8_t *optval;
362         uint16_t optcode;
363         size_t optlen;
364         bool found_clientid = false, found_iana = false, found_serverid = false;
365         int r;
366         struct in6_addr addr;
367         be32_t val;
368         uint32_t lt_pref, lt_valid;
369
370         assert_se(request->type == DHCP6_REQUEST);
371
372         assert_se(dhcp6_lease_new(&lease) >= 0);
373
374         while ((r = dhcp6_option_parse(&option, &len,
375                                        &optcode, &optlen, &optval)) >= 0) {
376                 switch(optcode) {
377                 case DHCP6_OPTION_CLIENTID:
378                         assert_se(!found_clientid);
379                         found_clientid = true;
380
381                         assert_se(!memcmp(optval, &test_duid,
382                                           sizeof(test_duid)));
383
384                         break;
385
386                 case DHCP6_OPTION_IA_NA:
387                         assert_se(!found_iana);
388                         found_iana = true;
389
390
391                         assert_se(optlen == 40);
392                         assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
393
394                         val = htobe32(80);
395                         assert_se(!memcmp(optval + 4, &val, sizeof(val)));
396
397                         val = htobe32(120);
398                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
399
400                         assert_se(!dhcp6_option_parse_ia(&optval, &optlen,
401                                                          optcode, &lease->ia));
402
403                         break;
404
405                 case DHCP6_OPTION_SERVERID:
406                         assert_se(!found_serverid);
407                         found_serverid = true;
408
409                         assert_se(optlen == 14);
410                         assert_se(!memcmp(&msg_advertise[179], optval, optlen));
411
412                         break;
413                 }
414         }
415
416         assert_se(r == -ENOMSG);
417         assert_se(found_clientid && found_iana && found_serverid);
418
419         assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
420                                                    &lt_valid) >= 0);
421         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
422         assert_se(lt_pref == 150);
423         assert_se(lt_valid == 180);
424
425         assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
426                                                   &lt_valid) == -ENOMSG);
427
428         return 0;
429 }
430
431 static int test_client_send_advertise(DHCP6Message *solicit)
432 {
433         DHCP6Message advertise;
434
435         advertise.transaction_id = solicit->transaction_id;
436         advertise.type = DHCP6_ADVERTISE;
437
438         memcpy(msg_advertise, &advertise.transaction_id, 4);
439
440         memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
441
442         memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
443
444         assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
445                   == sizeof(msg_advertise));
446
447         return 0;
448 }
449
450 static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
451                                       size_t len) {
452         uint8_t *optval;
453         uint16_t optcode;
454         size_t optlen;
455         bool found_clientid = false, found_iana = false;
456         int r;
457
458         assert_se(solicit->type == DHCP6_SOLICIT);
459
460         while ((r = dhcp6_option_parse(&option, &len,
461                                        &optcode, &optlen, &optval)) >= 0) {
462                 switch(optcode) {
463                 case DHCP6_OPTION_CLIENTID:
464                         assert_se(!found_clientid);
465                         found_clientid = true;
466
467                         assert_se(optlen == sizeof(test_duid));
468                         memcpy(&test_duid, optval, sizeof(test_duid));
469
470                         break;
471
472                 case DHCP6_OPTION_IA_NA:
473                         assert_se(!found_iana);
474                         found_iana = true;
475
476                         assert_se(optlen == 12);
477
478                         memcpy(&test_iaid, optval, sizeof(test_iaid));
479
480                         break;
481                 }
482         }
483
484         assert_se(r == -ENOMSG);
485         assert_se(found_clientid && found_iana);
486
487         return 0;
488 }
489
490 int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
491                                   const void *packet, size_t len) {
492         struct in6_addr mcast =
493                 IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
494         DHCP6Message *message;
495         uint8_t *option;
496
497         assert_se(s == test_dhcp_fd[0]);
498         assert_se(server_address);
499         assert_se(packet);
500         assert_se(len > sizeof(DHCP6Message) + 4);
501
502         assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
503
504         message = (DHCP6Message *)packet;
505         option = (uint8_t *)(message + 1);
506         len -= sizeof(DHCP6Message);
507
508         assert_se(message->transaction_id & 0x00ffffff);
509
510         if (test_client_message_num == 0) {
511                 test_client_verify_solicit(message, option, len);
512                 test_client_send_advertise(message);
513                 test_client_message_num++;
514         } else if (test_client_message_num == 1) {
515                 test_client_verify_request(message, option, len);
516                 test_client_send_reply(message);
517                 test_client_message_num++;
518         }
519
520         return len;
521 }
522
523 static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
524                                    void *userdata) {
525         sd_event *e = userdata;
526
527         assert_se(e);
528         assert_se(event == DHCP6_EVENT_IP_ACQUIRE);
529
530         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
531
532         if (verbose)
533                 printf("  got DHCPv6 event %d\n", event);
534
535         sd_event_exit(e, 0);
536 }
537
538 static int test_client_solicit(sd_event *e) {
539         sd_dhcp6_client *client;
540         usec_t time_now = now(CLOCK_MONOTONIC);
541
542         if (verbose)
543                 printf("* %s\n", __FUNCTION__);
544
545         assert_se(sd_dhcp6_client_new(&client) >= 0);
546         assert_se(client);
547
548         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
549
550         assert_se(sd_dhcp6_client_set_index(client, test_index) == 0);
551         assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
552
553         assert_se(sd_dhcp6_client_set_callback(client,
554                                                test_client_solicit_cb, e) >= 0);
555
556         assert_se(sd_event_add_time(e, &hangcheck, CLOCK_MONOTONIC,
557                                     time_now + 2 * USEC_PER_SEC, 0,
558                                     test_hangcheck, NULL) >= 0);
559
560         assert_se(sd_dhcp6_client_start(client) >= 0);
561
562         sd_event_loop(e);
563
564         hangcheck = sd_event_source_unref(hangcheck);
565
566         assert_se(!sd_dhcp6_client_unref(client));
567
568         test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
569
570         return 0;
571 }
572
573 int main(int argc, char *argv[]) {
574         _cleanup_event_unref_ sd_event *e;
575
576         assert_se(sd_event_new(&e) >= 0);
577
578         log_set_max_level(LOG_DEBUG);
579         log_parse_environment();
580         log_open();
581
582         test_client_basic(e);
583         test_option(e);
584         test_advertise_option(e);
585         test_client_solicit(e);
586
587         assert_se(!sd_event_unref(e));
588
589         return 0;
590 }