1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 Intel Corporation. All rights reserved.
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.
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.
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/>.
22 #include <netinet/icmp6.h>
24 #include "socket-util.h"
26 #include "dhcp6-internal.h"
27 #include "sd-icmp6-nd.h"
29 static struct ether_addr mac_addr = {
30 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
33 static bool verbose = false;
34 static sd_event_source *test_hangcheck;
35 static int test_fd[2];
37 static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
44 int dhcp_network_icmp6_bind_router_solicitation(int index) {
45 assert_se(index == 42);
47 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
53 static int send_ra(uint8_t flags) {
54 uint8_t advertisement[] = {
55 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
58 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
59 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
62 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
64 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
65 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
66 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
70 advertisement[5] = flags;
72 assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
73 sizeof(advertisement));
76 printf(" sent RA with flag 0x%02x\n", flags);
81 int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
85 static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) {
86 sd_event *e = userdata;
92 { 0, ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE },
93 { ND_RA_FLAG_OTHER, ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER },
94 { ND_RA_FLAG_MANAGED, ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED }
98 assert_se(event == flag_event[idx].event);
102 printf(" got event %d\n", event);
105 send_ra(flag_event[idx].flag);
110 static void test_rs(sd_event *e) {
111 usec_t time_now = now(clock_boottime_or_monotonic());
115 printf("* %s\n", __FUNCTION__);
117 assert_se(sd_icmp6_nd_new(&nd) >= 0);
120 assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);
122 assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0);
123 assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
124 assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0);
126 assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
127 time_now + 2 *USEC_PER_SEC, 0,
128 test_rs_hangcheck, NULL) >= 0);
130 assert_se(sd_icmp6_nd_stop(nd) >= 0);
131 assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
132 assert_se(sd_icmp6_nd_stop(nd) >= 0);
134 assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
138 test_hangcheck = sd_event_source_unref(test_hangcheck);
140 nd = sd_icmp6_nd_unref(nd);
146 int main(int argc, char *argv[]) {
149 assert_se(sd_event_new(&e) >= 0);
151 log_set_max_level(LOG_DEBUG);
152 log_parse_environment();