]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
24852172 | 2 | /*** |
810adae9 | 3 | Copyright © 2017 Intel Corporation. All rights reserved. |
24852172 PF |
4 | ***/ |
5 | ||
6 | #include <netinet/icmp6.h> | |
7 | #include <arpa/inet.h> | |
ca78ad1d | 8 | #include <unistd.h> |
24852172 PF |
9 | |
10 | #include "sd-radv.h" | |
11 | ||
12 | #include "alloc-util.h" | |
13 | #include "hexdecoct.h" | |
690afe79 | 14 | #include "icmp6-util-unix.h" |
24852172 PF |
15 | #include "socket-util.h" |
16 | #include "strv.h" | |
6d7c4033 | 17 | #include "tests.h" |
24852172 PF |
18 | |
19 | static struct ether_addr mac_addr = { | |
20 | .ether_addr_octet = { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 } | |
21 | }; | |
22 | ||
24852172 | 23 | static bool test_stopped; |
24852172 PF |
24 | static struct { |
25 | struct in6_addr address; | |
26 | unsigned char prefixlen; | |
27 | uint32_t valid; | |
28 | uint32_t preferred; | |
5238e957 | 29 | bool successful; |
24852172 PF |
30 | } prefix[] = { |
31 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64, | |
33 | 500, 440, true }, | |
34 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, | |
35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64, | |
36 | /* indicate default valid and preferred lifetimes for the test code */ | |
37 | 0, 0, true }, | |
38 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, | |
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58, | |
40 | 0, 0, | |
41 | /* indicate that this prefix already exists */ | |
42 | false }, | |
43 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, | |
44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120, | |
45 | 0, 0, | |
46 | /* indicate that this prefix already exists */ | |
47 | false }, | |
48 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, | |
49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12, | |
50 | 0, 0, | |
51 | /* indicate that this prefix already exists */ | |
52 | false }, | |
53 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad, | |
54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48, | |
55 | 0, 0, true }, | |
56 | { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad, | |
57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60, | |
58 | 0, 0, | |
59 | /* indicate that this prefix already exists */ | |
60 | false }, | |
61 | }; | |
62 | ||
06e6c805 PF |
63 | static const struct in6_addr test_rdnss = { { { 0x20, 0x01, 0x0d, 0xb8, |
64 | 0xde, 0xad, 0xbe, 0xef, | |
65 | 0x00, 0x00, 0x00, 0x00, | |
66 | 0x00, 0x00, 0x00, 0x01 } } }; | |
fa178dd2 PF |
67 | static const char *test_dnssl[] = { "lab.intra", |
68 | NULL }; | |
06e6c805 | 69 | |
68da8adf | 70 | TEST(radv_prefix) { |
24852172 PF |
71 | sd_radv_prefix *p; |
72 | ||
24852172 PF |
73 | assert_se(sd_radv_prefix_new(&p) >= 0); |
74 | ||
8161f608 | 75 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_onlink(NULL, true) < 0); |
24852172 PF |
76 | assert_se(sd_radv_prefix_set_onlink(p, true) >= 0); |
77 | assert_se(sd_radv_prefix_set_onlink(p, false) >= 0); | |
78 | ||
8161f608 | 79 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_address_autoconfiguration(NULL, true) < 0); |
24852172 PF |
80 | assert_se(sd_radv_prefix_set_address_autoconfiguration(p, true) >= 0); |
81 | assert_se(sd_radv_prefix_set_address_autoconfiguration(p, false) >= 0); | |
82 | ||
8161f608 | 83 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_valid_lifetime(NULL, 1, 1) < 0); |
95e104e0 YW |
84 | assert_se(sd_radv_prefix_set_valid_lifetime(p, 0, 0) >= 0); |
85 | assert_se(sd_radv_prefix_set_valid_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0); | |
86 | assert_se(sd_radv_prefix_set_valid_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0); | |
24852172 | 87 | |
8161f608 | 88 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_preferred_lifetime(NULL, 1, 1) < 0); |
95e104e0 YW |
89 | assert_se(sd_radv_prefix_set_preferred_lifetime(p, 0, 0) >= 0); |
90 | assert_se(sd_radv_prefix_set_preferred_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0); | |
91 | assert_se(sd_radv_prefix_set_preferred_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0); | |
24852172 | 92 | |
8161f608 YW |
93 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(NULL, NULL, 0) < 0); |
94 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, NULL, 0) < 0); | |
24852172 PF |
95 | |
96 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 64) >= 0); | |
97 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 0) < 0); | |
98 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 1) < 0); | |
99 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 2) < 0); | |
100 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 3) >= 0); | |
101 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 125) >= 0); | |
102 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 128) >= 0); | |
8161f608 YW |
103 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, &prefix[0].address, 129) < 0); |
104 | ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, &prefix[0].address, 255) < 0); | |
24852172 | 105 | |
8ff992d1 YW |
106 | assert_se(!sd_radv_prefix_unref(p)); |
107 | } | |
108 | ||
109 | TEST(radv_route_prefix) { | |
110 | sd_radv_route_prefix *p; | |
111 | ||
112 | assert_se(sd_radv_route_prefix_new(&p) >= 0); | |
113 | ||
8161f608 | 114 | ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_lifetime(NULL, 1, 1) < 0); |
8ff992d1 YW |
115 | assert_se(sd_radv_route_prefix_set_lifetime(p, 0, 0) >= 0); |
116 | assert_se(sd_radv_route_prefix_set_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0); | |
117 | assert_se(sd_radv_route_prefix_set_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0); | |
118 | ||
8161f608 YW |
119 | ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(NULL, NULL, 0) < 0); |
120 | ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, NULL, 0) < 0); | |
8ff992d1 YW |
121 | |
122 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 64) >= 0); | |
123 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 0) >= 0); | |
124 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 1) >= 0); | |
125 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 2) >= 0); | |
126 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 3) >= 0); | |
127 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 125) >= 0); | |
128 | assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 128) >= 0); | |
8161f608 YW |
129 | ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 129) < 0); |
130 | ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 255) < 0); | |
8ff992d1 YW |
131 | |
132 | assert_se(!sd_radv_route_prefix_unref(p)); | |
133 | } | |
134 | ||
135 | TEST(radv_pref64_prefix) { | |
136 | sd_radv_pref64_prefix *p; | |
137 | ||
138 | assert_se(sd_radv_pref64_prefix_new(&p) >= 0); | |
139 | ||
8161f608 YW |
140 | ASSERT_RETURN_EXPECTED_SE(sd_radv_pref64_prefix_set_prefix(NULL, NULL, 0, 0) < 0); |
141 | ASSERT_RETURN_EXPECTED_SE(sd_radv_pref64_prefix_set_prefix(p, NULL, 0, 0) < 0); | |
8ff992d1 YW |
142 | |
143 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 32, 300 * USEC_PER_SEC) >= 0); | |
144 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 40, 300 * USEC_PER_SEC) >= 0); | |
145 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 48, 300 * USEC_PER_SEC) >= 0); | |
146 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 56, 300 * USEC_PER_SEC) >= 0); | |
147 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 64, 300 * USEC_PER_SEC) >= 0); | |
148 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 96, 300 * USEC_PER_SEC) >= 0); | |
149 | ||
150 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 80, 300 * USEC_PER_SEC) < 0); | |
151 | assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 80, USEC_PER_DAY) < 0); | |
152 | ||
153 | assert_se(!sd_radv_pref64_prefix_unref(p)); | |
24852172 PF |
154 | } |
155 | ||
68da8adf | 156 | TEST(radv) { |
24852172 PF |
157 | sd_radv *ra; |
158 | ||
24852172 PF |
159 | assert_se(sd_radv_new(&ra) >= 0); |
160 | assert_se(ra); | |
161 | ||
8161f608 YW |
162 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(NULL, 0) < 0); |
163 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, 0) < 0); | |
164 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, -1) < 0); | |
165 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, -2) < 0); | |
24852172 PF |
166 | assert_se(sd_radv_set_ifindex(ra, 42) >= 0); |
167 | ||
8161f608 YW |
168 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(NULL, NULL) < 0); |
169 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(ra, NULL) >= 0); | |
24852172 PF |
170 | assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0); |
171 | ||
8161f608 YW |
172 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(NULL, 0) < 0); |
173 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra, 0) < 0); | |
174 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra, 1279) < 0); | |
24852172 PF |
175 | assert_se(sd_radv_set_mtu(ra, 1280) >= 0); |
176 | assert_se(sd_radv_set_mtu(ra, ~0) >= 0); | |
177 | ||
8161f608 | 178 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_hop_limit(NULL, 0) < 0); |
24852172 PF |
179 | assert_se(sd_radv_set_hop_limit(ra, 0) >= 0); |
180 | assert_se(sd_radv_set_hop_limit(ra, ~0) >= 0); | |
181 | ||
8161f608 | 182 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_router_lifetime(NULL, 0) < 0); |
24852172 | 183 | assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0); |
09457670 YW |
184 | assert_se(sd_radv_set_router_lifetime(ra, USEC_INFINITY) < 0); |
185 | assert_se(sd_radv_set_router_lifetime(ra, USEC_PER_YEAR) < 0); | |
186 | assert_se(sd_radv_set_router_lifetime(ra, 300 * USEC_PER_SEC) >= 0); | |
24852172 | 187 | |
8161f608 | 188 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(NULL, 0) < 0); |
24852172 PF |
189 | assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_LOW) >= 0); |
190 | assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0); | |
191 | assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0); | |
8161f608 | 192 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(ra, ~0) < 0); |
24852172 PF |
193 | |
194 | assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0); | |
09457670 | 195 | assert_se(sd_radv_set_router_lifetime(ra, 300 * USEC_PER_SEC) >= 0); |
24852172 PF |
196 | assert_se(sd_radv_set_router_lifetime(ra, 0) < 0); |
197 | assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0); | |
198 | assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0); | |
199 | ||
8161f608 | 200 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_managed_information(NULL, true) < 0); |
24852172 PF |
201 | assert_se(sd_radv_set_managed_information(ra, true) >= 0); |
202 | assert_se(sd_radv_set_managed_information(ra, false) >= 0); | |
203 | ||
8161f608 | 204 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_other_information(NULL, true) < 0); |
24852172 PF |
205 | assert_se(sd_radv_set_other_information(ra, true) >= 0); |
206 | assert_se(sd_radv_set_other_information(ra, false) >= 0); | |
207 | ||
8161f608 | 208 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_retransmit(NULL, 10 * USEC_PER_MSEC) < 0); |
8ff992d1 YW |
209 | assert_se(sd_radv_set_retransmit(ra, 10 * USEC_PER_MSEC) >= 0); |
210 | assert_se(sd_radv_set_retransmit(ra, 0) >= 0); | |
03401969 | 211 | assert_se(sd_radv_set_retransmit(ra, USEC_INFINITY) >= 0); |
8ff992d1 | 212 | |
8161f608 | 213 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_rdnss(NULL, 0, NULL, 0) < 0); |
06e6c805 | 214 | assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0); |
8161f608 | 215 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_rdnss(ra, 0, NULL, 128) < 0); |
eca280c8 YW |
216 | assert_se(sd_radv_set_rdnss(ra, 600 * USEC_PER_SEC, &test_rdnss, 0) >= 0); |
217 | assert_se(sd_radv_set_rdnss(ra, 600 * USEC_PER_SEC, &test_rdnss, 1) >= 0); | |
06e6c805 PF |
218 | assert_se(sd_radv_set_rdnss(ra, 0, &test_rdnss, 1) >= 0); |
219 | assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0); | |
220 | ||
fa178dd2 | 221 | assert_se(sd_radv_set_dnssl(ra, 0, NULL) >= 0); |
eca280c8 | 222 | assert_se(sd_radv_set_dnssl(ra, 600 * USEC_PER_SEC, NULL) >= 0); |
fa178dd2 | 223 | assert_se(sd_radv_set_dnssl(ra, 0, (char **)test_dnssl) >= 0); |
eca280c8 | 224 | assert_se(sd_radv_set_dnssl(ra, 600 * USEC_PER_SEC, (char **)test_dnssl) >= 0); |
fa178dd2 | 225 | |
8161f608 | 226 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_information(NULL, true) < 0); |
8ff992d1 YW |
227 | assert_se(sd_radv_set_home_agent_information(ra, true) >= 0); |
228 | assert_se(sd_radv_set_home_agent_information(ra, false) >= 0); | |
229 | ||
8161f608 | 230 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_preference(NULL, 10) < 0); |
8ff992d1 YW |
231 | assert_se(sd_radv_set_home_agent_preference(ra, 10) >= 0); |
232 | assert_se(sd_radv_set_home_agent_preference(ra, 0) >= 0); | |
233 | ||
8161f608 | 234 | ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_lifetime(NULL, 300 * USEC_PER_SEC) < 0); |
8ff992d1 YW |
235 | assert_se(sd_radv_set_home_agent_lifetime(ra, 300 * USEC_PER_SEC) >= 0); |
236 | assert_se(sd_radv_set_home_agent_lifetime(ra, 0) >= 0); | |
237 | assert_se(sd_radv_set_home_agent_lifetime(ra, USEC_PER_DAY) < 0); | |
238 | ||
24852172 PF |
239 | ra = sd_radv_unref(ra); |
240 | assert_se(!ra); | |
241 | } | |
242 | ||
a860df82 YW |
243 | static void dump_message(const uint8_t *buf, size_t len) { |
244 | assert(len >= sizeof(struct nd_router_advert)); | |
24852172 | 245 | |
a860df82 YW |
246 | printf("Received Router Advertisement with lifetime %i sec\n", |
247 | (buf[6] << 8) + buf[7]); | |
24852172 | 248 | |
a860df82 | 249 | for (size_t i = 0; i < len; i++) { |
06e6c805 | 250 | if (!(i % 8)) |
c0f86d66 | 251 | printf("%3zu: ", i); |
06e6c805 | 252 | |
24852172 PF |
253 | printf("0x%02x", buf[i]); |
254 | ||
24852172 PF |
255 | if ((i + 1) % 8) |
256 | printf(", "); | |
257 | else | |
258 | printf("\n"); | |
259 | } | |
a860df82 | 260 | } |
24852172 | 261 | |
a860df82 YW |
262 | static void verify_message(const uint8_t *buf, size_t len) { |
263 | static const uint8_t advertisement[] = { | |
264 | /* ICMPv6 Router Advertisement, no checksum */ | |
265 | 0x86, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0xb4, | |
266 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
267 | /* Source Link Layer Address Option */ | |
268 | 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, | |
269 | /* Prefix Information Option */ | |
270 | 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4, | |
271 | 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, | |
272 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
273 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
274 | /* Prefix Information Option */ | |
275 | 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x0e, 0x10, | |
276 | 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, | |
277 | 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d, | |
278 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
279 | /* Prefix Information Option */ | |
280 | 0x03, 0x04, 0x30, 0xc0, 0x00, 0x00, 0x0e, 0x10, | |
281 | 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, | |
282 | 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad, | |
283 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
284 | /* Recursive DNS Server Option */ | |
285 | 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, | |
286 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
287 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
288 | /* DNS Search List Option */ | |
289 | 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, | |
290 | 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, | |
291 | 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
292 | }; | |
293 | ||
294 | /* verify only up to known options, rest is not yet implemented */ | |
295 | for (size_t i = 0, m = MIN(len, sizeof(advertisement)); i < m; i++) { | |
296 | if (test_stopped) | |
19f3cc86 | 297 | /* on stop, many header fields are zero */ |
a860df82 | 298 | switch (i) { |
19f3cc86 YW |
299 | case 4: /* hop limit */ |
300 | case 5: /* flags */ | |
301 | case 6 ... 7: /* router lifetime */ | |
302 | case 8 ... 11: /* reachable time */ | |
303 | case 12 ... 15: /* retrans timer */ | |
a860df82 YW |
304 | assert_se(buf[i] == 0); |
305 | continue; | |
306 | } | |
24852172 | 307 | |
a860df82 YW |
308 | assert_se(buf[i] == advertisement[i]); |
309 | } | |
310 | } | |
311 | ||
312 | static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { | |
313 | sd_radv *ra = ASSERT_PTR(userdata); | |
314 | _cleanup_free_ uint8_t *buf = NULL; | |
315 | ssize_t buflen; | |
24852172 | 316 | |
a860df82 YW |
317 | buflen = next_datagram_size_fd(fd); |
318 | assert_se(buflen >= 0); | |
319 | assert_se(buf = new0(uint8_t, buflen)); | |
320 | ||
321 | assert_se(read(fd, buf, buflen) == buflen); | |
322 | ||
323 | dump_message(buf, buflen); | |
324 | verify_message(buf, buflen); | |
325 | ||
326 | if (test_stopped) { | |
327 | assert_se(sd_event_exit(sd_radv_get_event(ra), 0) >= 0); | |
24852172 PF |
328 | return 0; |
329 | } | |
330 | ||
290696e5 | 331 | assert_se(sd_radv_stop(ra) >= 0); |
24852172 | 332 | test_stopped = true; |
24852172 PF |
333 | return 0; |
334 | } | |
335 | ||
68da8adf | 336 | TEST(ra) { |
86d82cb8 YW |
337 | _cleanup_(sd_event_unrefp) sd_event *e = NULL; |
338 | _cleanup_(sd_event_source_unrefp) sd_event_source *recv_router_advertisement = NULL; | |
339 | _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL; | |
24852172 | 340 | |
3e29b889 | 341 | assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0); |
24852172 PF |
342 | |
343 | assert_se(sd_event_new(&e) >= 0); | |
344 | ||
345 | assert_se(sd_radv_new(&ra) >= 0); | |
346 | assert_se(ra); | |
347 | ||
348 | assert_se(sd_radv_attach_event(ra, e, 0) >= 0); | |
349 | ||
350 | assert_se(sd_radv_set_ifindex(ra, 42) >= 0); | |
351 | assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0); | |
09457670 | 352 | assert_se(sd_radv_set_router_lifetime(ra, 180 * USEC_PER_SEC) >= 0); |
24852172 PF |
353 | assert_se(sd_radv_set_hop_limit(ra, 64) >= 0); |
354 | assert_se(sd_radv_set_managed_information(ra, true) >= 0); | |
355 | assert_se(sd_radv_set_other_information(ra, true) >= 0); | |
eca280c8 YW |
356 | assert_se(sd_radv_set_rdnss(ra, 60 * USEC_PER_SEC, &test_rdnss, 1) >= 0); |
357 | assert_se(sd_radv_set_dnssl(ra, 60 * USEC_PER_SEC, (char **)test_dnssl) >= 0); | |
24852172 | 358 | |
86d82cb8 | 359 | for (unsigned i = 0; i < ELEMENTSOF(prefix); i++) { |
24852172 PF |
360 | sd_radv_prefix *p; |
361 | ||
362 | printf("Test prefix %u\n", i); | |
363 | assert_se(sd_radv_prefix_new(&p) >= 0); | |
364 | ||
365 | assert_se(sd_radv_prefix_set_prefix(p, &prefix[i].address, | |
366 | prefix[i].prefixlen) >= 0); | |
95e104e0 YW |
367 | if (prefix[i].valid > 0) |
368 | assert_se(sd_radv_prefix_set_valid_lifetime(p, prefix[i].valid * USEC_PER_SEC, USEC_INFINITY) >= 0); | |
369 | if (prefix[i].preferred > 0) | |
370 | assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred * USEC_PER_SEC, USEC_INFINITY) >= 0); | |
371 | ||
372 | assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].successful); | |
373 | /* If the previous sd_radv_add_prefix() succeeds, then also the second call should also succeed. */ | |
374 | assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].successful); | |
24852172 PF |
375 | |
376 | p = sd_radv_prefix_unref(p); | |
377 | assert_se(!p); | |
378 | } | |
379 | ||
86d82cb8 YW |
380 | assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0], EPOLLIN, radv_recv, ra) >= 0); |
381 | assert_se(sd_event_source_set_io_fd_own(recv_router_advertisement, true) >= 0); | |
24852172 | 382 | |
ba4e0427 | 383 | assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME, |
2e37084f YW |
384 | 2 * USEC_PER_SEC, 0, |
385 | NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0); | |
24852172 PF |
386 | |
387 | assert_se(sd_radv_start(ra) >= 0); | |
388 | ||
2e37084f | 389 | assert_se(sd_event_loop(e) >= 0); |
24852172 PF |
390 | } |
391 | ||
68da8adf | 392 | DEFINE_TEST_MAIN(LOG_DEBUG); |