]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/test-ndisc-rs.c
Merge pull request #2569 from zonque/removals
[thirdparty/systemd.git] / src / libsystemd-network / test-ndisc-rs.c
1 /***
2 This file is part of systemd.
3
4 Copyright (C) 2014 Intel Corporation. All rights reserved.
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <netinet/icmp6.h>
21
22 #include "sd-ndisc.h"
23
24 #include "icmp6-util.h"
25 #include "socket-util.h"
26
27 static struct ether_addr mac_addr = {
28 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
29 };
30
31 static bool verbose = false;
32 static sd_event_source *test_hangcheck;
33 static int test_fd[2];
34
35 typedef int (*send_ra_t)(uint8_t flags);
36 static send_ra_t send_ra_function;
37
38 static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
39 void *userdata) {
40 assert_se(false);
41
42 return 0;
43 }
44
45 int icmp6_bind_router_solicitation(int index) {
46 assert_se(index == 42);
47
48 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
49 return -errno;
50
51 return test_fd[0];
52 }
53
54 static int send_ra(uint8_t flags) {
55 uint8_t advertisement[] = {
56 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
59 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
60 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
63 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
65 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
66 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
67 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
69 };
70
71 advertisement[5] = flags;
72
73 assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
74 sizeof(advertisement));
75
76 if (verbose)
77 printf(" sent RA with flag 0x%02x\n", flags);
78
79 return 0;
80 }
81
82 int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
83 return send_ra_function(0);
84 }
85
86 static void test_rs_done(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) {
87 sd_event *e = userdata;
88 static unsigned idx = 0;
89 uint8_t flags_array[] = {
90 0,
91 0,
92 0,
93 ND_RA_FLAG_OTHER,
94 ND_RA_FLAG_MANAGED
95 };
96 uint32_t mtu;
97
98 assert_se(nd);
99
100 assert_se(flags == flags_array[idx]);
101 idx++;
102
103 if (verbose)
104 printf(" got event 0x%02x\n", flags);
105
106 if (idx < ELEMENTSOF(flags_array)) {
107 send_ra(flags_array[idx]);
108 return;
109 }
110
111 assert_se(sd_ndisc_get_mtu(nd, &mtu) == -ENOMSG);
112
113 sd_event_exit(e, 0);
114 }
115
116 static void test_rs(void) {
117 sd_event *e;
118 sd_ndisc *nd;
119 usec_t time_now = now(clock_boottime_or_monotonic());
120
121 if (verbose)
122 printf("* %s\n", __FUNCTION__);
123
124 send_ra_function = send_ra;
125
126 assert_se(sd_event_new(&e) >= 0);
127
128 assert_se(sd_ndisc_new(&nd) >= 0);
129 assert_se(nd);
130
131 assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
132
133 assert_se(sd_ndisc_set_index(nd, 42) >= 0);
134 assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
135 assert_se(sd_ndisc_set_callback(nd, test_rs_done, NULL, NULL, NULL, e) >= 0);
136
137 assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
138 time_now + 2 *USEC_PER_SEC, 0,
139 test_rs_hangcheck, NULL) >= 0);
140
141 assert_se(sd_ndisc_stop(nd) >= 0);
142 assert_se(sd_ndisc_router_discovery_start(nd) >= 0);
143 assert_se(sd_ndisc_stop(nd) >= 0);
144
145 assert_se(sd_ndisc_router_discovery_start(nd) >= 0);
146
147 sd_event_loop(e);
148
149 test_hangcheck = sd_event_source_unref(test_hangcheck);
150
151 nd = sd_ndisc_unref(nd);
152 assert_se(!nd);
153
154 close(test_fd[1]);
155
156 sd_event_unref(e);
157 }
158
159 int main(int argc, char *argv[]) {
160
161 log_set_max_level(LOG_DEBUG);
162 log_parse_environment();
163 log_open();
164
165 test_rs();
166
167 return 0;
168 }