LCOV - code coverage report
Current view: top level - libsystemd-network - test-ndisc-ra.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 155 166 93.4 %
Date: 2019-08-22 15:41:25 Functions: 6 10 60.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : /***
       3             :   Copyright © 2017 Intel Corporation. All rights reserved.
       4             : ***/
       5             : 
       6             : #include <netinet/icmp6.h>
       7             : #include <arpa/inet.h>
       8             : #include <unistd.h>
       9             : 
      10             : #include "sd-radv.h"
      11             : 
      12             : #include "alloc-util.h"
      13             : #include "hexdecoct.h"
      14             : #include "icmp6-util.h"
      15             : #include "socket-util.h"
      16             : #include "strv.h"
      17             : #include "tests.h"
      18             : 
      19             : static struct ether_addr mac_addr = {
      20             :         .ether_addr_octet = { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 }
      21             : };
      22             : 
      23             : static uint8_t advertisement[] = {
      24             :         /* ICMPv6 Router Advertisement, no checksum */
      25             :         0x86, 0x00, 0x00, 0x00,  0x40, 0xc0, 0x00, 0xb4,
      26             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      27             :         /* Source Link Layer Address Option */
      28             :         0x01, 0x01, 0x78, 0x2b,  0xcb, 0xb3, 0x6d, 0x53,
      29             :         /* Prefix Information Option */
      30             :         0x03, 0x04, 0x40, 0xc0,  0x00, 0x00, 0x01, 0xf4,
      31             :         0x00, 0x00, 0x01, 0xb8,  0x00, 0x00, 0x00, 0x00,
      32             :         0x20, 0x01, 0x0d, 0xb8,  0xde, 0xad, 0xbe, 0xef,
      33             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      34             :         /* Prefix Information Option */
      35             :         0x03, 0x04, 0x40, 0xc0,  0x00, 0x27, 0x8d, 0x00,
      36             :         0x00, 0x09, 0x3a, 0x80,  0x00, 0x00, 0x00, 0x00,
      37             :         0x20, 0x01, 0x0d, 0xb8,  0x0b, 0x16, 0xd0, 0x0d,
      38             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      39             :         /* Prefix Information Option */
      40             :         0x03, 0x04, 0x30, 0xc0,  0x00, 0x27, 0x8d, 0x00,
      41             :         0x00, 0x09, 0x3a, 0x80,  0x00, 0x00, 0x00, 0x00,
      42             :         0x20, 0x01, 0x0d, 0xb8,  0xc0, 0x01, 0x0d, 0xad,
      43             :         0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
      44             :         /* Recursive DNS Server Option */
      45             :         0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
      46             :         0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
      47             :         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
      48             :         /* DNS Search List Option */
      49             :         0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
      50             :         0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
      51             :         0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      52             : };
      53             : 
      54             : static sd_event_source *test_hangcheck;
      55             : static bool test_stopped;
      56             : static int test_fd[2];
      57             : static sd_event_source *recv_router_advertisement;
      58             : static struct {
      59             :         struct in6_addr address;
      60             :         unsigned char prefixlen;
      61             :         uint32_t valid;
      62             :         uint32_t preferred;
      63             :         bool successful;
      64             : } prefix[] = {
      65             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
      66             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
      67             :           500, 440, true },
      68             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
      69             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
      70             :           /* indicate default valid and preferred lifetimes for the test code */
      71             :           0, 0, true },
      72             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
      73             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58,
      74             :           0, 0,
      75             :           /* indicate that this prefix already exists */
      76             :           false },
      77             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
      78             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120,
      79             :           0, 0,
      80             :           /* indicate that this prefix already exists */
      81             :           false },
      82             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
      83             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12,
      84             :           0, 0,
      85             :           /* indicate that this prefix already exists */
      86             :           false },
      87             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
      88             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48,
      89             :           0, 0, true },
      90             :         { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
      91             :                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60,
      92             :           0, 0,
      93             :           /* indicate that this prefix already exists */
      94             :           false },
      95             : };
      96             : 
      97             : static const struct in6_addr test_rdnss = { { { 0x20, 0x01, 0x0d, 0xb8,
      98             :                                                 0xde, 0xad, 0xbe, 0xef,
      99             :                                                 0x00, 0x00, 0x00, 0x00,
     100             :                                                 0x00, 0x00, 0x00, 0x01 } } };
     101             : static const char *test_dnssl[] = { "lab.intra",
     102             :                                     NULL };
     103             : 
     104           0 : static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
     105             :                              void *userdata) {
     106           0 :         assert_se(false);
     107             : 
     108             :         return 0;
     109             : }
     110             : 
     111           1 : static void test_radv_prefix(void) {
     112             :         sd_radv_prefix *p;
     113             : 
     114           1 :         printf("* %s\n", __FUNCTION__);
     115             : 
     116           1 :         assert_se(sd_radv_prefix_new(&p) >= 0);
     117             : 
     118           1 :         assert_se(sd_radv_prefix_set_onlink(NULL, true) < 0);
     119           1 :         assert_se(sd_radv_prefix_set_onlink(p, true) >= 0);
     120           1 :         assert_se(sd_radv_prefix_set_onlink(p, false) >= 0);
     121             : 
     122           1 :         assert_se(sd_radv_prefix_set_address_autoconfiguration(NULL, true) < 0);
     123           1 :         assert_se(sd_radv_prefix_set_address_autoconfiguration(p, true) >= 0);
     124           1 :         assert_se(sd_radv_prefix_set_address_autoconfiguration(p, false) >= 0);
     125             : 
     126           1 :         assert_se(sd_radv_prefix_set_valid_lifetime(NULL, true) < 0);
     127           1 :         assert_se(sd_radv_prefix_set_valid_lifetime(p, ~0) >= 0);
     128           1 :         assert_se(sd_radv_prefix_set_valid_lifetime(p, 42) >= 0);
     129           1 :         assert_se(sd_radv_prefix_set_valid_lifetime(p, 0) >= 0);
     130             : 
     131           1 :         assert_se(sd_radv_prefix_set_preferred_lifetime(NULL, true) < 0);
     132           1 :         assert_se(sd_radv_prefix_set_preferred_lifetime(p, ~0) >= 0);
     133           1 :         assert_se(sd_radv_prefix_set_preferred_lifetime(p, 42) >= 0);
     134           1 :         assert_se(sd_radv_prefix_set_preferred_lifetime(p, 0) >= 0);
     135             : 
     136           1 :         assert_se(sd_radv_prefix_set_prefix(NULL, NULL, 0) < 0);
     137           1 :         assert_se(sd_radv_prefix_set_prefix(p, NULL, 0) < 0);
     138             : 
     139           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 64) >= 0);
     140           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 0) < 0);
     141           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 1) < 0);
     142           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 2) < 0);
     143           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 3) >= 0);
     144           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 125) >= 0);
     145           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 128) >= 0);
     146           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 129) < 0);
     147           1 :         assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 255) < 0);
     148             : 
     149           1 :         p = sd_radv_prefix_unref(p);
     150           1 :         assert_se(!p);
     151           1 : }
     152             : 
     153           1 : static void test_radv(void) {
     154             :         sd_radv *ra;
     155             : 
     156           1 :         printf("* %s\n", __FUNCTION__);
     157             : 
     158           1 :         assert_se(sd_radv_new(&ra) >= 0);
     159           1 :         assert_se(ra);
     160             : 
     161           1 :         assert_se(sd_radv_set_ifindex(NULL, 0) < 0);
     162           1 :         assert_se(sd_radv_set_ifindex(ra, 0) >= 0);
     163           1 :         assert_se(sd_radv_set_ifindex(ra, -1) >= 0);
     164           1 :         assert_se(sd_radv_set_ifindex(ra, -2) < 0);
     165           1 :         assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
     166             : 
     167           1 :         assert_se(sd_radv_set_mac(NULL, NULL) < 0);
     168           1 :         assert_se(sd_radv_set_mac(ra, NULL) >= 0);
     169           1 :         assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
     170             : 
     171           1 :         assert_se(sd_radv_set_mtu(NULL, 0) < 0);
     172           1 :         assert_se(sd_radv_set_mtu(ra, 0) < 0);
     173           1 :         assert_se(sd_radv_set_mtu(ra, 1279) < 0);
     174           1 :         assert_se(sd_radv_set_mtu(ra, 1280) >= 0);
     175           1 :         assert_se(sd_radv_set_mtu(ra, ~0) >= 0);
     176             : 
     177           1 :         assert_se(sd_radv_set_hop_limit(NULL, 0) < 0);
     178           1 :         assert_se(sd_radv_set_hop_limit(ra, 0) >= 0);
     179           1 :         assert_se(sd_radv_set_hop_limit(ra, ~0) >= 0);
     180             : 
     181           1 :         assert_se(sd_radv_set_router_lifetime(NULL, 0) < 0);
     182           1 :         assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
     183           1 :         assert_se(sd_radv_set_router_lifetime(ra, ~0) >= 0);
     184             : 
     185           1 :         assert_se(sd_radv_set_preference(NULL, 0) < 0);
     186           1 :         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_LOW) >= 0);
     187           1 :         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
     188           1 :         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
     189           1 :         assert_se(sd_radv_set_preference(ra, ~0) < 0);
     190             : 
     191           1 :         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
     192           1 :         assert_se(sd_radv_set_router_lifetime(ra, 42000) >= 0);
     193           1 :         assert_se(sd_radv_set_router_lifetime(ra, 0) < 0);
     194           1 :         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
     195           1 :         assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
     196             : 
     197           1 :         assert_se(sd_radv_set_managed_information(NULL, true) < 0);
     198           1 :         assert_se(sd_radv_set_managed_information(ra, true) >= 0);
     199           1 :         assert_se(sd_radv_set_managed_information(ra, false) >= 0);
     200             : 
     201           1 :         assert_se(sd_radv_set_other_information(NULL, true) < 0);
     202           1 :         assert_se(sd_radv_set_other_information(ra, true) >= 0);
     203           1 :         assert_se(sd_radv_set_other_information(ra, false) >= 0);
     204             : 
     205           1 :         assert_se(sd_radv_set_rdnss(NULL, 0, NULL, 0) < 0);
     206           1 :         assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0);
     207           1 :         assert_se(sd_radv_set_rdnss(ra, 0, NULL, 128) < 0);
     208           1 :         assert_se(sd_radv_set_rdnss(ra, 600, &test_rdnss, 0) >= 0);
     209           1 :         assert_se(sd_radv_set_rdnss(ra, 600, &test_rdnss, 1) >= 0);
     210           1 :         assert_se(sd_radv_set_rdnss(ra, 0, &test_rdnss, 1) >= 0);
     211           1 :         assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0);
     212             : 
     213           1 :         assert_se(sd_radv_set_dnssl(ra, 0, NULL) >= 0);
     214           1 :         assert_se(sd_radv_set_dnssl(ra, 600, NULL) >= 0);
     215           1 :         assert_se(sd_radv_set_dnssl(ra, 0, (char **)test_dnssl) >= 0);
     216           1 :         assert_se(sd_radv_set_dnssl(ra, 600, (char **)test_dnssl) >= 0);
     217             : 
     218           1 :         ra = sd_radv_unref(ra);
     219           1 :         assert_se(!ra);
     220           1 : }
     221             : 
     222           0 : int icmp6_bind_router_solicitation(int index) {
     223           0 :         return -ENOSYS;
     224             : }
     225             : 
     226           1 : int icmp6_bind_router_advertisement(int index) {
     227           1 :         assert_se(index == 42);
     228             : 
     229           1 :         return test_fd[1];
     230             : }
     231             : 
     232           0 : int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
     233             : 
     234           0 :         return 0;
     235             : }
     236             : 
     237           0 : int icmp6_receive(int fd, void *iov_base, size_t iov_len,
     238             :                   struct in6_addr *dst, triple_timestamp *timestamp) {
     239           0 :         assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
     240             : 
     241           0 :         if (timestamp)
     242           0 :                 triple_timestamp_get(timestamp);
     243             : 
     244           0 :         return 0;
     245             : }
     246             : 
     247           2 : static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
     248           2 :         sd_radv *ra = userdata;
     249             :         unsigned char buf[168];
     250             :         size_t i;
     251             : 
     252           2 :         assert_se(read(test_fd[0], &buf, sizeof(buf)) == sizeof(buf));
     253             : 
     254             :         /* router lifetime must be zero when test is stopped */
     255           2 :         if (test_stopped) {
     256           1 :                 advertisement[6] = 0x00;
     257           1 :                 advertisement[7] = 0x00;
     258             :         }
     259             : 
     260           2 :         printf ("Received Router Advertisement with lifetime %u\n",
     261           2 :                 (advertisement[6] << 8) + advertisement[7]);
     262             : 
     263             :         /* test only up to buf size, rest is not yet implemented */
     264         338 :         for (i = 0; i < sizeof(buf); i++) {
     265         336 :                 if (!(i % 8))
     266          42 :                         printf("%3zd: ", i);
     267             : 
     268         336 :                 printf("0x%02x", buf[i]);
     269             : 
     270         336 :                 assert_se(buf[i] == advertisement[i]);
     271             : 
     272         336 :                 if ((i + 1) % 8)
     273         294 :                         printf(", ");
     274             :                 else
     275          42 :                         printf("\n");
     276             :         }
     277             : 
     278           2 :         if (test_stopped) {
     279             :                 sd_event *e;
     280             : 
     281           1 :                 e = sd_radv_get_event(ra);
     282           1 :                 sd_event_exit(e, 0);
     283             : 
     284           1 :                 return 0;
     285             :         }
     286             : 
     287           1 :         assert_se(sd_radv_stop(ra) >= 0);
     288           1 :         test_stopped = true;
     289             : 
     290           1 :         return 0;
     291             : }
     292             : 
     293           1 : static void test_ra(void) {
     294             :         sd_event *e;
     295             :         sd_radv *ra;
     296           1 :         usec_t time_now = now(clock_boottime_or_monotonic());
     297             :         unsigned i;
     298             : 
     299           1 :         printf("* %s\n", __FUNCTION__);
     300             : 
     301           1 :         assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
     302             : 
     303           1 :         assert_se(sd_event_new(&e) >= 0);
     304             : 
     305           1 :         assert_se(sd_radv_new(&ra) >= 0);
     306           1 :         assert_se(ra);
     307             : 
     308           1 :         assert_se(sd_radv_attach_event(ra, e, 0) >= 0);
     309             : 
     310           1 :         assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
     311           1 :         assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
     312           1 :         assert_se(sd_radv_set_router_lifetime(ra, 180) >= 0);
     313           1 :         assert_se(sd_radv_set_hop_limit(ra, 64) >= 0);
     314           1 :         assert_se(sd_radv_set_managed_information(ra, true) >= 0);
     315           1 :         assert_se(sd_radv_set_other_information(ra, true) >= 0);
     316           1 :         assert_se(sd_radv_set_rdnss(ra, 60, &test_rdnss, 1) >= 0);
     317           1 :         assert_se(sd_radv_set_dnssl(ra, 60, (char **)test_dnssl) >= 0);
     318             : 
     319           8 :         for (i = 0; i < ELEMENTSOF(prefix); i++) {
     320             :                 sd_radv_prefix *p;
     321             : 
     322           7 :                 printf("Test prefix %u\n", i);
     323           7 :                 assert_se(sd_radv_prefix_new(&p) >= 0);
     324             : 
     325           7 :                 assert_se(sd_radv_prefix_set_prefix(p, &prefix[i].address,
     326             :                                                     prefix[i].prefixlen) >= 0);
     327           7 :                 if (prefix[i].valid)
     328           1 :                         assert_se(sd_radv_prefix_set_valid_lifetime(p, prefix[i].valid) >= 0);
     329           7 :                 if (prefix[i].preferred)
     330           1 :                         assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred) >= 0);
     331             : 
     332           7 :                 assert_se((sd_radv_add_prefix(ra, p, false) >= 0) == prefix[i].successful);
     333           7 :                 assert_se(sd_radv_add_prefix(ra, p, false) < 0);
     334             : 
     335           7 :                 p = sd_radv_prefix_unref(p);
     336           7 :                 assert_se(!p);
     337             :         }
     338             : 
     339           1 :         assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0],
     340             :                                   EPOLLIN, radv_recv, ra) >= 0);
     341             : 
     342           1 :         assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
     343             :                                  time_now + 2 *USEC_PER_SEC, 0,
     344             :                                  test_rs_hangcheck, NULL) >= 0);
     345             : 
     346           1 :         assert_se(sd_radv_start(ra) >= 0);
     347             : 
     348           1 :         sd_event_loop(e);
     349             : 
     350           1 :         test_hangcheck = sd_event_source_unref(test_hangcheck);
     351             : 
     352           1 :         ra = sd_radv_unref(ra);
     353           1 :         assert_se(!ra);
     354             : 
     355           1 :         close(test_fd[0]);
     356             : 
     357           1 :         sd_event_unref(e);
     358           1 : }
     359             : 
     360           1 : int main(int argc, char *argv[]) {
     361             : 
     362           1 :         test_setup_logging(LOG_DEBUG);
     363             : 
     364           1 :         test_radv_prefix();
     365           1 :         test_radv();
     366           1 :         test_ra();
     367             : 
     368           1 :         printf("* done\n");
     369           1 :         return 0;
     370             : }

Generated by: LCOV version 1.14