2 This file is part of systemd.
4 Copyright (C) 2014 Intel Corporation. All rights reserved.
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.
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.
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/>.
20 #include <netinet/icmp6.h>
24 #include "icmp6-util.h"
25 #include "socket-util.h"
27 static struct ether_addr mac_addr
= {
28 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}
31 static bool verbose
= false;
32 static sd_event_source
*test_hangcheck
;
33 static int test_fd
[2];
35 typedef int (*send_ra_t
)(uint8_t flags
);
36 static send_ra_t send_ra_function
;
38 static int test_rs_hangcheck(sd_event_source
*s
, uint64_t usec
,
45 int icmp6_bind_router_solicitation(int index
) {
46 assert_se(index
== 42);
48 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, test_fd
) < 0)
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,
71 advertisement
[5] = flags
;
73 assert_se(write(test_fd
[1], advertisement
, sizeof(advertisement
)) ==
74 sizeof(advertisement
));
77 printf(" sent RA with flag 0x%02x\n", flags
);
82 int icmp6_send_router_solicitation(int s
, const struct ether_addr
*ether_addr
) {
83 return send_ra_function(0);
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
[] = {
100 assert_se(flags
== flags_array
[idx
]);
104 printf(" got event 0x%02x\n", flags
);
106 if (idx
< ELEMENTSOF(flags_array
)) {
107 send_ra(flags_array
[idx
]);
111 assert_se(sd_ndisc_get_mtu(nd
, &mtu
) == -ENOMSG
);
116 static void test_rs(void) {
119 usec_t time_now
= now(clock_boottime_or_monotonic());
122 printf("* %s\n", __FUNCTION__
);
124 send_ra_function
= send_ra
;
126 assert_se(sd_event_new(&e
) >= 0);
128 assert_se(sd_ndisc_new(&nd
) >= 0);
131 assert_se(sd_ndisc_attach_event(nd
, e
, 0) >= 0);
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);
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);
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);
145 assert_se(sd_ndisc_router_discovery_start(nd
) >= 0);
149 test_hangcheck
= sd_event_source_unref(test_hangcheck
);
151 nd
= sd_ndisc_unref(nd
);
159 int main(int argc
, char *argv
[]) {
161 log_set_max_level(LOG_DEBUG
);
162 log_parse_environment();