1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2017 Intel Corporation. All rights reserved.
6 #include <net/ethernet.h>
7 #include <netinet/icmp6.h>
11 #include "sd-ndisc-protocol.h"
14 #include "alloc-util.h"
15 #include "icmp6-test-util.h"
16 #include "in-addr-util.h"
17 #include "radv-internal.h"
18 #include "socket-util.h"
21 static struct ether_addr mac_addr
= {
22 .ether_addr_octet
= { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 }
25 static bool test_stopped
;
27 struct in6_addr address
;
28 unsigned char prefixlen
;
33 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
36 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
38 /* indicate default valid and preferred lifetimes for the test code */
40 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58,
43 /* indicate that this prefix already exists */
45 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120,
48 /* indicate that this prefix already exists */
50 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12,
53 /* indicate that this prefix already exists */
55 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48,
58 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60,
61 /* indicate that this prefix already exists */
65 static const struct in6_addr test_rdnss
= { { { 0x20, 0x01, 0x0d, 0xb8,
66 0xde, 0xad, 0xbe, 0xef,
67 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x01 } } };
69 static const char *test_dnssl
[] = { "lab.intra",
75 assert_se(sd_radv_new(&ra
) >= 0);
78 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(NULL
, 0) < 0);
79 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra
, 0) < 0);
80 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra
, -1) < 0);
81 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra
, -2) < 0);
82 assert_se(sd_radv_set_ifindex(ra
, 42) >= 0);
85 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_hop_limit(NULL
, 0) < 0);
86 assert_se(sd_radv_set_hop_limit(ra
, 0) >= 0);
87 assert_se(sd_radv_set_hop_limit(ra
, ~0) >= 0);
89 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_router_lifetime(NULL
, 0) < 0);
90 assert_se(sd_radv_set_router_lifetime(ra
, 0) >= 0);
91 assert_se(sd_radv_set_router_lifetime(ra
, USEC_INFINITY
) < 0);
92 assert_se(sd_radv_set_router_lifetime(ra
, USEC_PER_YEAR
) < 0);
93 assert_se(sd_radv_set_router_lifetime(ra
, 300 * USEC_PER_SEC
) >= 0);
95 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(NULL
, 0) < 0);
96 assert_se(sd_radv_set_preference(ra
, SD_NDISC_PREFERENCE_LOW
) >= 0);
97 assert_se(sd_radv_set_preference(ra
, SD_NDISC_PREFERENCE_MEDIUM
) >= 0);
98 assert_se(sd_radv_set_preference(ra
, SD_NDISC_PREFERENCE_HIGH
) >= 0);
99 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(ra
, ~0) < 0);
101 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_managed_information(NULL
, true) < 0);
102 assert_se(sd_radv_set_managed_information(ra
, true) >= 0);
103 assert_se(sd_radv_set_managed_information(ra
, false) >= 0);
105 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_other_information(NULL
, true) < 0);
106 assert_se(sd_radv_set_other_information(ra
, true) >= 0);
107 assert_se(sd_radv_set_other_information(ra
, false) >= 0);
109 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_reachable_time(NULL
, 10 * USEC_PER_MSEC
) < 0);
110 assert_se(sd_radv_set_reachable_time(ra
, 10 * USEC_PER_MSEC
) >= 0);
111 assert_se(sd_radv_set_reachable_time(ra
, 0) >= 0);
112 assert_se(sd_radv_set_reachable_time(ra
, USEC_INFINITY
) >= 0);
114 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_retransmit(NULL
, 10 * USEC_PER_MSEC
) < 0);
115 assert_se(sd_radv_set_retransmit(ra
, 10 * USEC_PER_MSEC
) >= 0);
116 assert_se(sd_radv_set_retransmit(ra
, 0) >= 0);
117 assert_se(sd_radv_set_retransmit(ra
, USEC_INFINITY
) >= 0);
120 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(NULL
, NULL
) < 0);
121 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(ra
, NULL
) >= 0);
122 assert_se(sd_radv_set_mac(ra
, &mac_addr
) >= 0);
123 sd_radv_unset_mac(ra
);
125 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(NULL
, 0) < 0);
126 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra
, 0) < 0);
127 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra
, 1279) < 0);
128 assert_se(sd_radv_set_mtu(ra
, 1280) >= 0);
129 assert_se(sd_radv_set_mtu(ra
, 9999) >= 0);
130 sd_radv_unset_mtu(ra
);
132 ASSERT_RETURN_EXPECTED_SE(sd_radv_add_rdnss(NULL
, 0, NULL
, 0, 0) < 0);
133 ASSERT_RETURN_EXPECTED_SE(sd_radv_add_rdnss(ra
, 0, NULL
, 0, 0) < 0);
134 assert_se(sd_radv_add_rdnss(ra
, 0, &test_rdnss
, 600 * USEC_PER_SEC
, USEC_INFINITY
) < 0);
135 assert_se(sd_radv_add_rdnss(ra
, 1, &test_rdnss
, 600 * USEC_PER_SEC
, USEC_INFINITY
) >= 0);
136 assert_se(sd_radv_add_rdnss(ra
, 1, &test_rdnss
, 0, 0) >= 0);
137 sd_radv_clear_rdnss(ra
);
139 ASSERT_RETURN_EXPECTED_SE(sd_radv_add_dnssl(NULL
, NULL
, 0, 0) < 0);
140 assert_se(sd_radv_add_dnssl(ra
, NULL
, 0, 0) < 0);
141 assert_se(sd_radv_add_dnssl(ra
, NULL
, 600 * USEC_PER_SEC
, USEC_INFINITY
) < 0);
142 assert_se(sd_radv_add_dnssl(ra
, (char**) test_dnssl
, 600 * USEC_PER_SEC
, USEC_INFINITY
) >= 0);
143 assert_se(sd_radv_add_dnssl(ra
, (char**) test_dnssl
, 0, 0) >= 0);
144 sd_radv_clear_dnssl(ra
);
146 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent(NULL
, 0, 0, 0) < 0);
147 assert_se(sd_radv_set_home_agent(ra
, 0, 0, 0) >= 0);
148 assert_se(sd_radv_set_home_agent(ra
, 10, 300 * USEC_PER_SEC
, USEC_INFINITY
) >= 0);
149 sd_radv_unset_home_agent(ra
);
151 ra
= sd_radv_unref(ra
);
155 static void dump_message(const uint8_t *buf
, size_t len
) {
156 assert(len
>= sizeof(struct nd_router_advert
));
158 printf("Received Router Advertisement with lifetime %i sec\n",
159 (buf
[6] << 8) + buf
[7]);
161 for (size_t i
= 0; i
< len
; i
++) {
165 printf("0x%02x", buf
[i
]);
174 static void verify_message(const uint8_t *buf
, size_t len
) {
175 static const uint8_t advertisement
[] = {
176 /* ICMPv6 Router Advertisement, no checksum */
177 0x86, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0xb4,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 /* Source Link Layer Address Option */
180 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
181 /* Prefix Information Option */
182 0x03, 0x04, 0x30, 0xc0, 0x00, 0x00, 0x0e, 0x10,
183 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
184 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 /* Prefix Information Option */
187 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x0e, 0x10,
188 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
189 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 /* Prefix Information Option */
192 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
193 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
194 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 /* Recursive DNS Server Option */
197 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
198 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
200 /* DNS Search List Option */
201 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
202 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
203 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 /* verify only up to known options, rest is not yet implemented */
207 for (size_t i
= 0, m
= MIN(len
, sizeof(advertisement
)); i
< m
; i
++) {
209 /* on stop, many header fields are zero */
211 case 4: /* hop limit */
213 case 6 ... 7: /* router lifetime */
214 case 8 ... 11: /* reachable time */
215 case 12 ... 15: /* retrans timer */
216 assert_se(buf
[i
] == 0);
220 assert_se(buf
[i
] == advertisement
[i
]);
224 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
225 sd_radv
*ra
= ASSERT_PTR(userdata
);
226 _cleanup_free_
uint8_t *buf
= NULL
;
229 buflen
= next_datagram_size_fd(fd
);
230 assert_se(buflen
>= 0);
231 assert_se(buf
= new0(uint8_t, buflen
));
233 assert_se(read(fd
, buf
, buflen
) == buflen
);
235 dump_message(buf
, buflen
);
236 verify_message(buf
, buflen
);
239 assert_se(sd_event_exit(sd_radv_get_event(ra
), 0) >= 0);
243 assert_se(sd_radv_stop(ra
) >= 0);
249 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
250 _cleanup_(sd_event_source_unrefp
) sd_event_source
*recv_router_advertisement
= NULL
;
251 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
253 assert_se(socketpair(AF_UNIX
, SOCK_SEQPACKET
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) >= 0);
255 assert_se(sd_event_new(&e
) >= 0);
257 assert_se(sd_radv_new(&ra
) >= 0);
260 assert_se(sd_radv_attach_event(ra
, e
, 0) >= 0);
262 assert_se(sd_radv_set_ifindex(ra
, 42) >= 0);
263 assert_se(sd_radv_set_router_lifetime(ra
, 180 * USEC_PER_SEC
) >= 0);
264 assert_se(sd_radv_set_hop_limit(ra
, 64) >= 0);
265 assert_se(sd_radv_set_managed_information(ra
, true) >= 0);
266 assert_se(sd_radv_set_other_information(ra
, true) >= 0);
267 assert_se(sd_radv_set_mac(ra
, &mac_addr
) >= 0);
268 assert_se(sd_radv_add_rdnss(ra
, 1, &test_rdnss
, 60 * USEC_PER_SEC
, USEC_INFINITY
) >= 0);
269 assert_se(sd_radv_add_dnssl(ra
, (char**) test_dnssl
, 60 * USEC_PER_SEC
, USEC_INFINITY
) >= 0);
271 FOREACH_ARRAY(p
, prefix
, ELEMENTSOF(prefix
)) {
272 printf("Test prefix %s\n", IN6_ADDR_PREFIX_TO_STRING(&p
->address
, p
->prefixlen
));
273 assert_se((sd_radv_add_prefix(
277 ND_OPT_PI_FLAG_ONLINK
| ND_OPT_PI_FLAG_AUTO
,
278 p
->valid
> 0 ? p
->valid
* USEC_PER_SEC
: RADV_DEFAULT_VALID_LIFETIME_USEC
,
279 p
->preferred
> 0 ? p
->preferred
* USEC_PER_SEC
: RADV_DEFAULT_PREFERRED_LIFETIME_USEC
,
281 USEC_INFINITY
) >= 0) == p
->successful
);
282 /* If the previous sd_radv_add_prefix() succeeds, then also the second call should also succeed. */
283 assert_se((sd_radv_add_prefix(
287 ND_OPT_PI_FLAG_ONLINK
| ND_OPT_PI_FLAG_AUTO
,
288 p
->valid
> 0 ? p
->valid
* USEC_PER_SEC
: RADV_DEFAULT_VALID_LIFETIME_USEC
,
289 p
->preferred
> 0 ? p
->preferred
* USEC_PER_SEC
: RADV_DEFAULT_PREFERRED_LIFETIME_USEC
,
291 USEC_INFINITY
) >= 0) == p
->successful
);
294 assert_se(sd_event_add_io(e
, &recv_router_advertisement
, test_fd
[0], EPOLLIN
, radv_recv
, ra
) >= 0);
295 assert_se(sd_event_source_set_io_fd_own(recv_router_advertisement
, true) >= 0);
297 assert_se(sd_event_add_time_relative(e
, NULL
, CLOCK_BOOTTIME
,
298 30 * USEC_PER_SEC
, 0,
299 NULL
, INT_TO_PTR(-ETIMEDOUT
)) >= 0);
301 assert_se(sd_radv_start(ra
) >= 0);
303 assert_se(sd_event_loop(e
) >= 0);
306 DEFINE_TEST_MAIN(LOG_DEBUG
);