LCOV - code coverage report
Current view: top level - libsystemd-network - test-dhcp6-client.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 464 476 97.5 %
Date: 2019-08-22 15:41:25 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : /***
       3             :   Copyright © 2014 Intel Corporation. All rights reserved.
       4             : ***/
       5             : 
       6             : #include <net/ethernet.h>
       7             : #include <net/if_arp.h>
       8             : #include <stdbool.h>
       9             : #include <stdio.h>
      10             : #include <sys/socket.h>
      11             : #include <sys/types.h>
      12             : #include <unistd.h>
      13             : 
      14             : #include "sd-dhcp6-client.h"
      15             : #include "sd-event.h"
      16             : 
      17             : #include "dhcp6-internal.h"
      18             : #include "dhcp6-lease-internal.h"
      19             : #include "dhcp6-protocol.h"
      20             : #include "fd-util.h"
      21             : #include "macro.h"
      22             : #include "memory-util.h"
      23             : #include "socket-util.h"
      24             : #include "tests.h"
      25             : #include "time-util.h"
      26             : #include "virt.h"
      27             : 
      28             : static struct ether_addr mac_addr = {
      29             :         .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
      30             : };
      31             : 
      32             : static sd_event_source *hangcheck;
      33             : static int test_dhcp_fd[2];
      34             : static int test_index = 42;
      35             : static int test_client_message_num;
      36             : static be32_t test_iaid = 0;
      37             : static uint8_t test_duid[14] = { };
      38             : 
      39           1 : static int test_client_basic(sd_event *e) {
      40             :         sd_dhcp6_client *client;
      41             :         int v;
      42             : 
      43           1 :         log_debug("/* %s */", __func__);
      44             : 
      45           1 :         assert_se(sd_dhcp6_client_new(&client) >= 0);
      46           1 :         assert_se(client);
      47             : 
      48           1 :         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
      49             : 
      50           1 :         assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
      51           1 :         assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL);
      52           1 :         assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0);
      53           1 :         assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
      54             : 
      55           1 :         assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
      56             :                                           sizeof (mac_addr),
      57             :                                           ARPHRD_ETHER) >= 0);
      58             : 
      59           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1);
      60           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1);
      61           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1);
      62           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
      63           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
      64             : 
      65           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL);
      66           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
      67           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST);
      68           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST);
      69           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
      70           1 :         assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
      71             : 
      72           1 :         assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
      73           1 :         v = 0;
      74           1 :         assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
      75           1 :         assert_se(v);
      76           1 :         assert_se(sd_dhcp6_client_set_information_request(client, 0) >= 0);
      77           1 :         v = 42;
      78           1 :         assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
      79           1 :         assert_se(v == 0);
      80             : 
      81           1 :         v = 0;
      82           1 :         assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
      83           1 :         assert_se(v);
      84           1 :         v = 0;
      85           1 :         assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
      86           1 :         assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
      87           1 :         assert_se(v);
      88           1 :         v = 42;
      89           1 :         assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
      90           1 :         assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
      91           1 :         assert_se(v);
      92             : 
      93           1 :         assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
      94           1 :         assert_se(sd_dhcp6_client_set_prefix_delegation(client, 1) >= 0);
      95           1 :         v = 0;
      96           1 :         assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
      97           1 :         assert_se(v);
      98           1 :         v = 0;
      99           1 :         assert_se(sd_dhcp6_client_get_prefix_delegation(client, &v) >= 0);
     100           1 :         assert_se(v);
     101             : 
     102           1 :         assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
     103             : 
     104           1 :         assert_se(sd_dhcp6_client_detach_event(client) >= 0);
     105           1 :         assert_se(!sd_dhcp6_client_unref(client));
     106             : 
     107           1 :         return 0;
     108             : }
     109             : 
     110           1 : static int test_option(sd_event *e) {
     111           1 :         uint8_t packet[] = {
     112             :                 'F', 'O', 'O',
     113             :                 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x07,
     114             :                 'A', 'B', 'C', 'D', 'E', 'F', 'G',
     115             :                 0x00, SD_DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
     116             :                 '1', '2', '3', '4', '5', '6', '7', '8', '9',
     117             :                 'B', 'A', 'R',
     118             :         };
     119           1 :         uint8_t result[] = {
     120             :                 'F', 'O', 'O',
     121             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     122             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     123             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     124             :                 'B', 'A', 'R',
     125             :         };
     126             :         uint16_t optcode;
     127             :         size_t optlen;
     128             :         uint8_t *optval, *buf, *out;
     129           1 :         size_t zero = 0, pos = 3;
     130           1 :         size_t buflen = sizeof(packet), outlen = sizeof(result);
     131             : 
     132           1 :         log_debug("/* %s */", __func__);
     133             : 
     134           1 :         assert_se(buflen == outlen);
     135             : 
     136           1 :         assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
     137             :                                      &optval) == -ENOMSG);
     138             : 
     139           1 :         buflen -= 3;
     140           1 :         buf = &packet[3];
     141           1 :         outlen -= 3;
     142           1 :         out = &result[3];
     143             : 
     144           1 :         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
     145             :                                      &optval) >= 0);
     146           1 :         pos += 4 + optlen;
     147           1 :         assert_se(buf == &packet[pos]);
     148           1 :         assert_se(optcode == SD_DHCP6_OPTION_ORO);
     149           1 :         assert_se(optlen == 7);
     150           1 :         assert_se(buflen + pos == sizeof(packet));
     151             : 
     152           1 :         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
     153             :                                       optval) >= 0);
     154           1 :         assert_se(out == &result[pos]);
     155           1 :         assert_se(*out == 0x00);
     156             : 
     157           1 :         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
     158             :                                      &optval) >= 0);
     159           1 :         pos += 4 + optlen;
     160           1 :         assert_se(buf == &packet[pos]);
     161           1 :         assert_se(optcode == SD_DHCP6_OPTION_VENDOR_CLASS);
     162           1 :         assert_se(optlen == 9);
     163           1 :         assert_se(buflen + pos == sizeof(packet));
     164             : 
     165           1 :         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
     166             :                                       optval) >= 0);
     167           1 :         assert_se(out == &result[pos]);
     168           1 :         assert_se(*out == 'B');
     169             : 
     170           1 :         assert_se(memcmp(packet, result, sizeof(packet)) == 0);
     171             : 
     172           1 :         return 0;
     173             : }
     174             : 
     175           1 : static int test_option_status(sd_event *e) {
     176           1 :         uint8_t option1[] = {
     177             :                 /* IA NA */
     178             :                 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d,
     179             :                 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
     180             :                 /* status option */
     181             :                 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
     182             :         };
     183             :         static const uint8_t option2[] = {
     184             :                 /* IA NA */
     185             :                 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d,
     186             :                 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
     187             :                 /* IA Addr */
     188             :                 0x00, 0x05, 0x00, 0x1e,
     189             :                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     190             :                 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
     191             :                 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
     192             :                 /* status option */
     193             :                 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
     194             :         };
     195             :         static const uint8_t option3[] = {
     196             :                 /* IA NA */
     197             :                 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d,
     198             :                 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
     199             :                 /* IA Addr */
     200             :                 0x00, 0x05, 0x00, 0x24,
     201             :                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     202             :                 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
     203             :                 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
     204             :                 /* status option */
     205             :                 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 'f',  'o',
     206             :                 'o',  'b',  'a',  'r',
     207             :         };
     208             :         static const uint8_t option4[] = {
     209             :                 /* IA PD */
     210             :                 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d,
     211             :                 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
     212             :                 /* IA PD Prefix */
     213             :                 0x00, 0x1a, 0x00, 0x1f,
     214             :                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     215             :                 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
     216             :                 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     217             :                 0x00,
     218             :                 /* status option */
     219             :                 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
     220             :         };
     221             :         static const uint8_t option5[] = {
     222             :                 /* IA PD */
     223             :                 0x00, 0x19, 0x00, 0x52, 0x1a, 0x1d, 0x1a, 0x1d,
     224             :                 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
     225             :                 /* IA PD Prefix #1 */
     226             :                 0x00, 0x1a, 0x00, 0x1f,
     227             :                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     228             :                 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
     229             :                 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     230             :                 0x00,
     231             :                 /* status option */
     232             :                 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
     233             :                 /* IA PD Prefix #2 */
     234             :                 0x00, 0x1a, 0x00, 0x1f,
     235             :                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     236             :                 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x0l, 0xd0,
     237             :                 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     238             :                 0x00,
     239             :                 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
     240             :         };
     241             :         DHCP6Option *option;
     242             :         DHCP6IA ia, pd;
     243           1 :         int r = 0;
     244             : 
     245           1 :         log_debug("/* %s */", __func__);
     246             : 
     247           1 :         zero(ia);
     248           1 :         option = (DHCP6Option *)option1;
     249           1 :         assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
     250             : 
     251           1 :         r = dhcp6_option_parse_ia(option, &ia);
     252           1 :         assert_se(r == -EINVAL);
     253           1 :         assert_se(ia.addresses == NULL);
     254             : 
     255           1 :         option->len = htobe16(17);
     256           1 :         r = dhcp6_option_parse_ia(option, &ia);
     257           1 :         assert_se(r == -ENOBUFS);
     258           1 :         assert_se(ia.addresses == NULL);
     259             : 
     260           1 :         option->len = htobe16(sizeof(DHCP6Option));
     261           1 :         r = dhcp6_option_parse_ia(option, &ia);
     262           1 :         assert_se(r == -ENOBUFS);
     263           1 :         assert_se(ia.addresses == NULL);
     264             : 
     265           1 :         zero(ia);
     266           1 :         option = (DHCP6Option *)option2;
     267           1 :         assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
     268             : 
     269           1 :         r = dhcp6_option_parse_ia(option, &ia);
     270           1 :         assert_se(r >= 0);
     271           1 :         assert_se(ia.addresses == NULL);
     272             : 
     273           1 :         zero(ia);
     274           1 :         option = (DHCP6Option *)option3;
     275           1 :         assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
     276             : 
     277           1 :         r = dhcp6_option_parse_ia(option, &ia);
     278           1 :         assert_se(r >= 0);
     279           1 :         assert_se(ia.addresses != NULL);
     280           1 :         dhcp6_lease_free_ia(&ia);
     281             : 
     282           1 :         zero(pd);
     283           1 :         option = (DHCP6Option *)option4;
     284           1 :         assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
     285             : 
     286           1 :         r = dhcp6_option_parse_ia(option, &pd);
     287           1 :         assert_se(r == 0);
     288           1 :         assert_se(pd.addresses != NULL);
     289           1 :         assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
     290           1 :         assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0);
     291           1 :         assert_se(memcmp(&pd.ia_pd.lifetime_t2, &option4[12], 4) == 0);
     292           1 :         dhcp6_lease_free_ia(&pd);
     293             : 
     294           1 :         zero(pd);
     295           1 :         option = (DHCP6Option *)option5;
     296           1 :         assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
     297             : 
     298           1 :         r = dhcp6_option_parse_ia(option, &pd);
     299           1 :         assert_se(r == 0);
     300           1 :         assert_se(pd.addresses != NULL);
     301           1 :         dhcp6_lease_free_ia(&pd);
     302             : 
     303           1 :         return 0;
     304             : }
     305             : 
     306             : static uint8_t msg_advertise[198] = {
     307             :         0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
     308             :         0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
     309             :         0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
     310             :         0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
     311             :         0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
     312             :         0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
     313             :         0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
     314             :         0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
     315             :         0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
     316             :         0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
     317             :         0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
     318             :         0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
     319             :         0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
     320             :         0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
     321             :         0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
     322             :         0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
     323             :         0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
     324             :         0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
     325             :         0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
     326             :         0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
     327             :         0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
     328             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
     329             :         0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
     330             :         0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
     331             :         0x53, 0x00, 0x07, 0x00, 0x01, 0x00
     332             : };
     333             : 
     334             : static uint8_t msg_reply[173] = {
     335             :         0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
     336             :         0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
     337             :         0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
     338             :         0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
     339             :         0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
     340             :         0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
     341             :         0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
     342             :         0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
     343             :         0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
     344             :         0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
     345             :         0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
     346             :         0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
     347             :         0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
     348             :         0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
     349             :         0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
     350             :         0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
     351             :         0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     352             :         0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
     353             :         0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
     354             :         0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
     355             :         0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
     356             :         0x00, 0x00, 0x00, 0x00, 0x01
     357             : };
     358             : 
     359             : static uint8_t fqdn_wire[16] = {
     360             :         0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b',
     361             :         0x05, 'i', 'n', 't', 'r', 'a', 0x00
     362             : };
     363             : 
     364           1 : static int test_advertise_option(sd_event *e) {
     365           2 :         _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
     366           1 :         DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
     367           1 :         size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0;
     368             :         be32_t val;
     369           1 :         uint8_t preference = 255;
     370             :         struct in6_addr addr;
     371             :         uint32_t lt_pref, lt_valid;
     372             :         int r;
     373             :         uint8_t *opt;
     374           1 :         bool opt_clientid = false;
     375             :         struct in6_addr *addrs;
     376             :         char **domains;
     377             : 
     378           1 :         log_debug("/* %s */", __func__);
     379             : 
     380           1 :         assert_se(len >= sizeof(DHCP6Message));
     381             : 
     382           1 :         assert_se(dhcp6_lease_new(&lease) >= 0);
     383             : 
     384           1 :         assert_se(advertise->type == DHCP6_ADVERTISE);
     385           1 :         assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
     386             :                   0x0fb4e5);
     387             : 
     388           8 :         while (pos < len) {
     389           7 :                 DHCP6Option *option = (DHCP6Option *)&advertise->options[pos];
     390           7 :                 const uint16_t optcode = be16toh(option->code);
     391           7 :                 const uint16_t optlen = be16toh(option->len);
     392           7 :                 uint8_t *optval = option->data;
     393             : 
     394           7 :                 switch(optcode) {
     395           1 :                 case SD_DHCP6_OPTION_CLIENTID:
     396           1 :                         assert_se(optlen == 14);
     397             : 
     398           1 :                         opt_clientid = true;
     399           1 :                         break;
     400             : 
     401           1 :                 case SD_DHCP6_OPTION_IA_NA:
     402           1 :                         assert_se(optlen == 94);
     403           1 :                         assert_se(!memcmp(optval, &msg_advertise[26], optlen));
     404             : 
     405           1 :                         val = htobe32(0x0ecfa37d);
     406           1 :                         assert_se(!memcmp(optval, &val, sizeof(val)));
     407             : 
     408           1 :                         val = htobe32(80);
     409           1 :                         assert_se(!memcmp(optval + 4, &val, sizeof(val)));
     410             : 
     411           1 :                         val = htobe32(120);
     412           1 :                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
     413             : 
     414           1 :                         assert_se(dhcp6_option_parse_ia(option, &lease->ia) >= 0);
     415             : 
     416           1 :                         break;
     417             : 
     418           1 :                 case SD_DHCP6_OPTION_SERVERID:
     419           1 :                         assert_se(optlen == 14);
     420           1 :                         assert_se(!memcmp(optval, &msg_advertise[179], optlen));
     421             : 
     422           1 :                         assert_se(dhcp6_lease_set_serverid(lease, optval,
     423             :                                                            optlen) >= 0);
     424           1 :                         break;
     425             : 
     426           1 :                 case SD_DHCP6_OPTION_PREFERENCE:
     427           1 :                         assert_se(optlen == 1);
     428           1 :                         assert_se(!*optval);
     429             : 
     430           1 :                         assert_se(dhcp6_lease_set_preference(lease,
     431             :                                                              *optval) >= 0);
     432           1 :                         break;
     433             : 
     434           0 :                 case SD_DHCP6_OPTION_ELAPSED_TIME:
     435           0 :                         assert_se(optlen == 2);
     436             : 
     437           0 :                         break;
     438             : 
     439           1 :                 case SD_DHCP6_OPTION_DNS_SERVERS:
     440           1 :                         assert_se(optlen == 16);
     441           1 :                         assert_se(dhcp6_lease_set_dns(lease, optval,
     442             :                                                       optlen) >= 0);
     443           1 :                         break;
     444             : 
     445           1 :                 case SD_DHCP6_OPTION_DOMAIN_LIST:
     446           1 :                         assert_se(optlen == 11);
     447           1 :                         assert_se(dhcp6_lease_set_domains(lease, optval,
     448             :                                                           optlen) >= 0);
     449           1 :                         break;
     450             : 
     451           1 :                 case SD_DHCP6_OPTION_SNTP_SERVERS:
     452           1 :                         assert_se(optlen == 16);
     453           1 :                         assert_se(dhcp6_lease_set_sntp(lease, optval,
     454             :                                                        optlen) >= 0);
     455           1 :                         break;
     456             : 
     457           0 :                 default:
     458           0 :                         break;
     459             :                 }
     460             : 
     461           7 :                 pos += sizeof(*option) + optlen;
     462             :         }
     463             : 
     464           1 :         assert_se(pos == len);
     465           1 :         assert_se(opt_clientid);
     466             : 
     467           1 :         sd_dhcp6_lease_reset_address_iter(lease);
     468           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     469             :                                              &lt_valid) >= 0);
     470           1 :         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
     471           1 :         assert_se(lt_pref == 150);
     472           1 :         assert_se(lt_valid == 180);
     473           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     474             :                                              &lt_valid) == -ENOMSG);
     475             : 
     476           1 :         sd_dhcp6_lease_reset_address_iter(lease);
     477           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     478             :                                              &lt_valid) >= 0);
     479           1 :         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
     480           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     481             :                                              &lt_valid) == -ENOMSG);
     482           1 :         sd_dhcp6_lease_reset_address_iter(lease);
     483           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     484             :                                              &lt_valid) >= 0);
     485           1 :         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
     486           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     487             :                                              &lt_valid) == -ENOMSG);
     488             : 
     489           1 :         assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
     490           1 :         assert_se(len == 14);
     491           1 :         assert_se(!memcmp(opt, &msg_advertise[179], len));
     492             : 
     493           1 :         assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
     494           1 :         assert_se(preference == 0);
     495             : 
     496           1 :         r = sd_dhcp6_lease_get_dns(lease, &addrs);
     497           1 :         assert_se(r == 1);
     498           1 :         assert_se(!memcmp(addrs, &msg_advertise[124], r * 16));
     499             : 
     500           1 :         r = sd_dhcp6_lease_get_domains(lease, &domains);
     501           1 :         assert_se(r == 1);
     502           1 :         assert_se(!strcmp("lab.intra", domains[0]));
     503           1 :         assert_se(domains[1] == NULL);
     504             : 
     505           1 :         r = sd_dhcp6_lease_get_ntp_addrs(lease, &addrs);
     506           1 :         assert_se(r == 1);
     507           1 :         assert_se(!memcmp(addrs, &msg_advertise[159], r * 16));
     508             : 
     509           1 :         return 0;
     510             : }
     511             : 
     512           0 : static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
     513           0 :         assert_not_reached("Test case should have completed in 2 seconds");
     514             : 
     515             :         return 0;
     516             : }
     517             : 
     518           1 : static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
     519             :                                    void *userdata) {
     520           1 :         sd_event *e = userdata;
     521             :         sd_dhcp6_lease *lease;
     522             :         struct in6_addr *addrs;
     523             :         char **domains;
     524             : 
     525           1 :         log_debug("/* %s */", __func__);
     526             : 
     527           1 :         assert_se(e);
     528           1 :         assert_se(event == SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE);
     529             : 
     530           1 :         assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
     531             : 
     532           1 :         assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
     533           1 :         assert_se(!strcmp("lab.intra", domains[0]));
     534           1 :         assert_se(domains[1] == NULL);
     535             : 
     536           1 :         assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
     537           1 :         assert_se(!memcmp(addrs, &msg_advertise[124], 16));
     538             : 
     539           1 :         assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
     540           1 :         assert_se(!memcmp(addrs, &msg_advertise[159], 16));
     541             : 
     542           1 :         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
     543             : 
     544           1 :         sd_event_exit(e, 0);
     545           1 : }
     546             : 
     547           2 : static int test_client_send_reply(DHCP6Message *request) {
     548             :         DHCP6Message reply;
     549             : 
     550           2 :         reply.transaction_id = request->transaction_id;
     551           2 :         reply.type = DHCP6_REPLY;
     552             : 
     553           2 :         memcpy(msg_reply, &reply.transaction_id, 4);
     554             : 
     555           2 :         memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
     556             : 
     557           2 :         memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
     558             : 
     559           2 :         assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
     560             :                   == sizeof(msg_reply));
     561             : 
     562           2 :         return 0;
     563             : }
     564             : 
     565           1 : static int test_client_verify_request(DHCP6Message *request, size_t len) {
     566           2 :         _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
     567           1 :         size_t pos = 0;
     568           1 :         bool found_clientid = false, found_iana = false, found_serverid = false,
     569           1 :                 found_elapsed_time = false, found_fqdn = false;
     570             :         struct in6_addr addr;
     571             :         be32_t val;
     572             :         uint32_t lt_pref, lt_valid;
     573             : 
     574           1 :         log_debug("/* %s */", __func__);
     575             : 
     576           1 :         assert_se(request->type == DHCP6_REQUEST);
     577           1 :         assert_se(dhcp6_lease_new(&lease) >= 0);
     578             : 
     579           1 :         len -= sizeof(DHCP6Message);
     580             : 
     581           7 :         while (pos < len) {
     582           6 :                 DHCP6Option *option = (DHCP6Option *)&request->options[pos];
     583           6 :                 uint16_t optcode = be16toh(option->code);
     584           6 :                 uint16_t optlen = be16toh(option->len);
     585           6 :                 uint8_t *optval = option->data;
     586             : 
     587           6 :                 switch(optcode) {
     588           1 :                 case SD_DHCP6_OPTION_CLIENTID:
     589           1 :                         assert_se(!found_clientid);
     590           1 :                         found_clientid = true;
     591             : 
     592           1 :                         assert_se(!memcmp(optval, &test_duid,
     593             :                                           sizeof(test_duid)));
     594             : 
     595           1 :                         break;
     596             : 
     597           1 :                 case SD_DHCP6_OPTION_IA_NA:
     598           1 :                         assert_se(!found_iana);
     599           1 :                         found_iana = true;
     600             : 
     601           1 :                         assert_se(optlen == 40);
     602           1 :                         assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
     603             : 
     604           1 :                         val = htobe32(80);
     605           1 :                         assert_se(!memcmp(optval + 4, &val, sizeof(val)));
     606             : 
     607           1 :                         val = htobe32(120);
     608           1 :                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
     609             : 
     610           1 :                         assert_se(!dhcp6_option_parse_ia(option, &lease->ia));
     611             : 
     612           1 :                         break;
     613             : 
     614           1 :                 case SD_DHCP6_OPTION_SERVERID:
     615           1 :                         assert_se(!found_serverid);
     616           1 :                         found_serverid = true;
     617             : 
     618           1 :                         assert_se(optlen == 14);
     619           1 :                         assert_se(!memcmp(&msg_advertise[179], optval, optlen));
     620             : 
     621           1 :                         break;
     622             : 
     623           1 :                 case SD_DHCP6_OPTION_ELAPSED_TIME:
     624           1 :                         assert_se(!found_elapsed_time);
     625           1 :                         found_elapsed_time = true;
     626             : 
     627           1 :                         assert_se(optlen == 2);
     628             : 
     629           1 :                         break;
     630           1 :                 case SD_DHCP6_OPTION_FQDN:
     631           1 :                         assert_se(!found_fqdn);
     632           1 :                         found_fqdn = true;
     633             : 
     634           1 :                         assert_se(optlen == 17);
     635             : 
     636           1 :                         assert_se(optval[0] == 0x01);
     637           1 :                         assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
     638           1 :                         break;
     639             :                 }
     640             : 
     641           6 :                 pos += sizeof(*option) + optlen;
     642             :         }
     643             : 
     644           1 :         assert_se(found_clientid && found_iana && found_serverid &&
     645             :                   found_elapsed_time);
     646             : 
     647           1 :         sd_dhcp6_lease_reset_address_iter(lease);
     648           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     649             :                                              &lt_valid) >= 0);
     650           1 :         assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
     651           1 :         assert_se(lt_pref == 150);
     652           1 :         assert_se(lt_valid == 180);
     653             : 
     654           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     655             :                                              &lt_valid) == -ENOMSG);
     656             : 
     657           1 :         return 0;
     658             : }
     659             : 
     660           1 : static int test_client_send_advertise(DHCP6Message *solicit) {
     661             :         DHCP6Message advertise;
     662             : 
     663           1 :         advertise.transaction_id = solicit->transaction_id;
     664           1 :         advertise.type = DHCP6_ADVERTISE;
     665             : 
     666           1 :         memcpy(msg_advertise, &advertise.transaction_id, 4);
     667             : 
     668           1 :         memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
     669             : 
     670           1 :         memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
     671             : 
     672           1 :         assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
     673             :                   == sizeof(msg_advertise));
     674             : 
     675           1 :         return 0;
     676             : }
     677             : 
     678           1 : static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) {
     679           1 :         bool found_clientid = false, found_iana = false,
     680           1 :                 found_elapsed_time = false, found_fqdn = false;
     681           1 :         size_t pos = 0;
     682             : 
     683           1 :         log_debug("/* %s */", __func__);
     684             : 
     685           1 :         assert_se(solicit->type == DHCP6_SOLICIT);
     686             : 
     687           1 :         len -= sizeof(DHCP6Message);
     688             : 
     689           7 :         while (pos < len) {
     690           6 :                 DHCP6Option *option = (DHCP6Option *)&solicit->options[pos];
     691           6 :                 uint16_t optcode = be16toh(option->code);
     692           6 :                 uint16_t optlen = be16toh(option->len);
     693           6 :                 uint8_t *optval = option->data;
     694             : 
     695           6 :                 switch(optcode) {
     696           1 :                 case SD_DHCP6_OPTION_CLIENTID:
     697           1 :                         assert_se(!found_clientid);
     698           1 :                         found_clientid = true;
     699             : 
     700           1 :                         assert_se(optlen == sizeof(test_duid));
     701           1 :                         memcpy(&test_duid, optval, sizeof(test_duid));
     702             : 
     703           1 :                         break;
     704             : 
     705           1 :                 case SD_DHCP6_OPTION_IA_NA:
     706           1 :                         assert_se(!found_iana);
     707           1 :                         found_iana = true;
     708             : 
     709           1 :                         assert_se(optlen == 12);
     710             : 
     711           1 :                         memcpy(&test_iaid, optval, sizeof(test_iaid));
     712             : 
     713           1 :                         break;
     714             : 
     715           1 :                 case SD_DHCP6_OPTION_ELAPSED_TIME:
     716           1 :                         assert_se(!found_elapsed_time);
     717           1 :                         found_elapsed_time = true;
     718             : 
     719           1 :                         assert_se(optlen == 2);
     720             : 
     721           1 :                         break;
     722             : 
     723           1 :                 case SD_DHCP6_OPTION_FQDN:
     724           1 :                         assert_se(!found_fqdn);
     725           1 :                         found_fqdn = true;
     726             : 
     727           1 :                         assert_se(optlen == 17);
     728             : 
     729           1 :                         assert_se(optval[0] == 0x01);
     730           1 :                         assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
     731             : 
     732           1 :                         break;
     733             :                 }
     734             : 
     735           6 :                 pos += sizeof(*option) + optlen;
     736             :         }
     737             : 
     738           1 :         assert_se(pos == len);
     739           1 :         assert_se(found_clientid && found_iana && found_elapsed_time);
     740             : 
     741           1 :         return 0;
     742             : }
     743             : 
     744           1 : static void test_client_information_cb(sd_dhcp6_client *client, int event,
     745             :                                        void *userdata) {
     746           1 :         sd_event *e = userdata;
     747             :         sd_dhcp6_lease *lease;
     748             :         struct in6_addr *addrs;
     749           1 :         struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
     750             :         char **domains;
     751             : 
     752           1 :         log_debug("/* %s */", __func__);
     753             : 
     754           1 :         assert_se(e);
     755           1 :         assert_se(event == SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST);
     756             : 
     757           1 :         assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
     758             : 
     759           1 :         assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
     760           1 :         assert_se(!strcmp("lab.intra", domains[0]));
     761           1 :         assert_se(domains[1] == NULL);
     762             : 
     763           1 :         assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
     764           1 :         assert_se(!memcmp(addrs, &msg_advertise[124], 16));
     765             : 
     766           1 :         assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
     767           1 :         assert_se(!memcmp(addrs, &msg_advertise[159], 16));
     768             : 
     769           1 :         assert_se(sd_dhcp6_client_set_information_request(client, false) == -EBUSY);
     770           1 :         assert_se(sd_dhcp6_client_set_callback(client, NULL, e) >= 0);
     771           1 :         assert_se(sd_dhcp6_client_stop(client) >= 0);
     772           1 :         assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
     773             : 
     774           1 :         assert_se(sd_dhcp6_client_set_callback(client,
     775             :                                                test_client_solicit_cb, e) >= 0);
     776             : 
     777           1 :         assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
     778             : 
     779           1 :         assert_se(sd_dhcp6_client_start(client) >= 0);
     780             : 
     781           1 : }
     782             : 
     783           1 : static int test_client_verify_information_request(DHCP6Message *information_request,
     784             :                                                   size_t len) {
     785             : 
     786           2 :         _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
     787           1 :         size_t pos = 0;
     788           1 :         bool found_clientid = false, found_elapsed_time = false;
     789             :         struct in6_addr addr;
     790             :         uint32_t lt_pref, lt_valid;
     791             : 
     792           1 :         log_debug("/* %s */", __func__);
     793             : 
     794           1 :         assert_se(information_request->type == DHCP6_INFORMATION_REQUEST);
     795           1 :         assert_se(dhcp6_lease_new(&lease) >= 0);
     796             : 
     797           1 :         len -= sizeof(DHCP6Message);
     798             : 
     799           4 :         while (pos < len) {
     800           3 :                 DHCP6Option *option = (DHCP6Option *)&information_request->options[pos];
     801           3 :                 uint16_t optcode = be16toh(option->code);
     802           3 :                 uint16_t optlen = be16toh(option->len);
     803           3 :                 uint8_t *optval = option->data;
     804             : 
     805           3 :                 switch(optcode) {
     806           1 :                 case SD_DHCP6_OPTION_CLIENTID:
     807           1 :                         assert_se(!found_clientid);
     808           1 :                         found_clientid = true;
     809             : 
     810           1 :                         assert_se(optlen == sizeof(test_duid));
     811           1 :                         memcpy(&test_duid, optval, sizeof(test_duid));
     812             : 
     813           1 :                         break;
     814             : 
     815           0 :                 case SD_DHCP6_OPTION_IA_NA:
     816           0 :                         assert_not_reached("IA TA option must not be present");
     817             : 
     818             :                         break;
     819             : 
     820           0 :                 case SD_DHCP6_OPTION_SERVERID:
     821           0 :                         assert_not_reached("Server ID option must not be present");
     822             : 
     823             :                         break;
     824             : 
     825           1 :                 case SD_DHCP6_OPTION_ELAPSED_TIME:
     826           1 :                         assert_se(!found_elapsed_time);
     827           1 :                         found_elapsed_time = true;
     828             : 
     829           1 :                         assert_se(optlen == 2);
     830             : 
     831           1 :                         break;
     832             :                 }
     833             : 
     834           3 :                 pos += sizeof(*option) + optlen;
     835             :         }
     836             : 
     837           1 :         assert_se(pos == len);
     838           1 :         assert_se(found_clientid && found_elapsed_time);
     839             : 
     840           1 :         sd_dhcp6_lease_reset_address_iter(lease);
     841             : 
     842           1 :         assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
     843             :                                              &lt_valid) == -ENOMSG);
     844             : 
     845           1 :         return 0;
     846             : }
     847             : 
     848           3 : int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
     849             :                                   const void *packet, size_t len) {
     850           3 :         struct in6_addr mcast =
     851             :                 IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
     852             :         DHCP6Message *message;
     853             : 
     854           3 :         assert_se(s == test_dhcp_fd[0]);
     855           3 :         assert_se(server_address);
     856           3 :         assert_se(packet);
     857           3 :         assert_se(len > sizeof(DHCP6Message) + 4);
     858           3 :         assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
     859             : 
     860           3 :         message = (DHCP6Message *)packet;
     861             : 
     862           3 :         assert_se(message->transaction_id & 0x00ffffff);
     863             : 
     864           3 :         if (test_client_message_num == 0) {
     865           1 :                 test_client_verify_information_request(message, len);
     866           1 :                 test_client_send_reply(message);
     867           1 :                 test_client_message_num++;
     868           2 :         } else if (test_client_message_num == 1) {
     869           1 :                 test_client_verify_solicit(message, len);
     870           1 :                 test_client_send_advertise(message);
     871           1 :                 test_client_message_num++;
     872           1 :         } else if (test_client_message_num == 2) {
     873           1 :                 test_client_verify_request(message, len);
     874           1 :                 test_client_send_reply(message);
     875           1 :                 test_client_message_num++;
     876             :         }
     877             : 
     878           3 :         return len;
     879             : }
     880             : 
     881           2 : int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
     882           2 :         assert_se(index == test_index);
     883             : 
     884           2 :         if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) < 0)
     885           0 :                 return -errno;
     886             : 
     887           2 :         return test_dhcp_fd[0];
     888             : }
     889             : 
     890           1 : static int test_client_solicit(sd_event *e) {
     891             :         sd_dhcp6_client *client;
     892           1 :         usec_t time_now = now(clock_boottime_or_monotonic());
     893           1 :         struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
     894             :         int val;
     895             : 
     896           1 :         log_debug("/* %s */", __func__);
     897             : 
     898           1 :         assert_se(sd_dhcp6_client_new(&client) >= 0);
     899           1 :         assert_se(client);
     900             : 
     901           1 :         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
     902             : 
     903           1 :         assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0);
     904           1 :         assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
     905             :                                           sizeof (mac_addr),
     906             :                                           ARPHRD_ETHER) >= 0);
     907           1 :         assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);
     908             : 
     909           1 :         assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
     910           1 :         assert_se(val == 0);
     911           1 :         assert_se(sd_dhcp6_client_set_information_request(client, 42) >= 0);
     912           1 :         assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
     913           1 :         assert_se(val);
     914             : 
     915           1 :         assert_se(sd_dhcp6_client_set_callback(client,
     916             :                                                test_client_information_cb, e) >= 0);
     917             : 
     918           1 :         assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(),
     919             :                                     time_now + 2 * USEC_PER_SEC, 0,
     920             :                                     test_hangcheck, NULL) >= 0);
     921             : 
     922           1 :         assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
     923             : 
     924           1 :         assert_se(sd_dhcp6_client_start(client) >= 0);
     925             : 
     926           1 :         sd_event_loop(e);
     927             : 
     928           1 :         hangcheck = sd_event_source_unref(hangcheck);
     929             : 
     930           1 :         assert_se(!sd_dhcp6_client_unref(client));
     931             : 
     932           1 :         test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
     933             : 
     934           1 :         return 0;
     935             : }
     936             : 
     937           1 : int main(int argc, char *argv[]) {
     938           1 :         _cleanup_(sd_event_unrefp) sd_event *e;
     939             : 
     940           1 :         assert_se(sd_event_new(&e) >= 0);
     941             : 
     942           1 :         test_setup_logging(LOG_DEBUG);
     943             : 
     944           1 :         test_client_basic(e);
     945           1 :         test_option(e);
     946           1 :         test_option_status(e);
     947           1 :         test_advertise_option(e);
     948           1 :         test_client_solicit(e);
     949             : 
     950           1 :         return 0;
     951             : }

Generated by: LCOV version 1.14