]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-ndisc-rs.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / libsystemd-network / test-ndisc-rs.c
CommitLineData
f20a35cc
PF
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright (C) 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 <netinet/icmp6.h>
23
07630cea 24#include "sd-ndisc.h"
f20a35cc 25
940367a0 26#include "icmp6-util.h"
07630cea 27#include "socket-util.h"
f20a35cc
PF
28
29static struct ether_addr mac_addr = {
30 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
31};
32
33static bool verbose = false;
34static sd_event_source *test_hangcheck;
35static int test_fd[2];
36
99af546d
PF
37typedef int (*send_ra_t)(uint8_t flags);
38static send_ra_t send_ra_function;
39
f20a35cc
PF
40static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
41 void *userdata) {
787784c4 42 assert_se(false);
f20a35cc
PF
43
44 return 0;
45}
46
940367a0 47int icmp6_bind_router_solicitation(int index) {
787784c4 48 assert_se(index == 42);
f20a35cc
PF
49
50 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
51 return -errno;
52
53 return test_fd[0];
54}
55
56static int send_ra(uint8_t flags) {
57 uint8_t advertisement[] = {
58 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
61 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
62 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
65 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
67 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
68 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
69 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
71 };
72
73 advertisement[5] = flags;
74
787784c4 75 assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
f20a35cc
PF
76 sizeof(advertisement));
77
78 if (verbose)
79 printf(" sent RA with flag 0x%02x\n", flags);
80
81 return 0;
82}
83
940367a0 84int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
99af546d 85 return send_ra_function(0);
f20a35cc
PF
86}
87
4d7b83da 88static void test_rs_done(sd_ndisc *nd, int event, void *userdata) {
f20a35cc
PF
89 sd_event *e = userdata;
90 static int idx = 0;
91 struct {
92 uint8_t flag;
93 int event;
94 } flag_event[] = {
4d7b83da
TG
95 { 0, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_NONE },
96 { ND_RA_FLAG_OTHER, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_OTHER },
97 { ND_RA_FLAG_MANAGED, SD_NDISC_EVENT_ROUTER_ADVERTISMENT_MANAGED }
f20a35cc 98 };
8d7f2c6a
PF
99 uint32_t mtu;
100
787784c4 101 assert_se(nd);
f20a35cc 102
787784c4 103 assert_se(event == flag_event[idx].event);
f20a35cc
PF
104 idx++;
105
106 if (verbose)
107 printf(" got event %d\n", event);
108
8d7f2c6a 109 if (idx < 3) {
f20a35cc 110 send_ra(flag_event[idx].flag);
8d7f2c6a
PF
111 return;
112 }
113
4d7b83da 114 assert_se(sd_ndisc_get_mtu(nd, &mtu) == -ENOMSG);
8d7f2c6a
PF
115
116 sd_event_exit(e, 0);
f20a35cc
PF
117}
118
99af546d
PF
119static void test_rs(void) {
120 sd_event *e;
4d7b83da 121 sd_ndisc *nd;
99af546d 122 usec_t time_now = now(clock_boottime_or_monotonic());
f20a35cc
PF
123
124 if (verbose)
125 printf("* %s\n", __FUNCTION__);
126
99af546d
PF
127 send_ra_function = send_ra;
128
129 assert_se(sd_event_new(&e) >= 0);
130
4d7b83da 131 assert_se(sd_ndisc_new(&nd) >= 0);
787784c4 132 assert_se(nd);
f20a35cc 133
4d7b83da 134 assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
f20a35cc 135
4d7b83da
TG
136 assert_se(sd_ndisc_set_index(nd, 42) >= 0);
137 assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
138 assert_se(sd_ndisc_set_callback(nd, test_rs_done, e) >= 0);
f20a35cc 139
787784c4 140 assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
f20a35cc
PF
141 time_now + 2 *USEC_PER_SEC, 0,
142 test_rs_hangcheck, NULL) >= 0);
143
4d7b83da
TG
144 assert_se(sd_ndisc_stop(nd) >= 0);
145 assert_se(sd_ndisc_router_discovery_start(nd) >= 0);
146 assert_se(sd_ndisc_stop(nd) >= 0);
836cf090 147
4d7b83da 148 assert_se(sd_ndisc_router_discovery_start(nd) >= 0);
f20a35cc
PF
149
150 sd_event_loop(e);
151
152 test_hangcheck = sd_event_source_unref(test_hangcheck);
153
4d7b83da 154 nd = sd_ndisc_unref(nd);
787784c4 155 assert_se(!nd);
f20a35cc 156
f20a35cc 157 close(test_fd[1]);
99af546d
PF
158
159 sd_event_unref(e);
f20a35cc
PF
160}
161
162int main(int argc, char *argv[]) {
f20a35cc
PF
163
164 log_set_max_level(LOG_DEBUG);
165 log_parse_environment();
166 log_open();
167
99af546d 168 test_rs();
f20a35cc
PF
169
170 return 0;
171}