]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-icmp6-rs.c
sd-icmp6-nd: Add helper function to get the IPv6 link MTU
[thirdparty/systemd.git] / src / libsystemd-network / test-icmp6-rs.c
CommitLineData
f20a35cc
PF
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright (C) 2014 Intel Corporation. All rights reserved.
7
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.
12
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.
17
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/>.
20***/
21
22#include <netinet/icmp6.h>
23
24#include "socket-util.h"
25
26#include "dhcp6-internal.h"
27#include "sd-icmp6-nd.h"
28
29static struct ether_addr mac_addr = {
30 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
31};
32
33static bool verbose = false;
34static sd_event_source *test_hangcheck;
35static int test_fd[2];
36
37static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
38 void *userdata) {
787784c4 39 assert_se(false);
f20a35cc
PF
40
41 return 0;
42}
43
44int dhcp_network_icmp6_bind_router_solicitation(int index) {
787784c4 45 assert_se(index == 42);
f20a35cc
PF
46
47 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
48 return -errno;
49
50 return test_fd[0];
51}
52
53static 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,
68 };
69
70 advertisement[5] = flags;
71
787784c4 72 assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
f20a35cc
PF
73 sizeof(advertisement));
74
75 if (verbose)
76 printf(" sent RA with flag 0x%02x\n", flags);
77
78 return 0;
79}
80
81int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
82 return send_ra(0);
83}
84
85static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) {
86 sd_event *e = userdata;
87 static int idx = 0;
88 struct {
89 uint8_t flag;
90 int event;
91 } flag_event[] = {
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 }
95 };
787784c4 96 assert_se(nd);
f20a35cc 97
787784c4 98 assert_se(event == flag_event[idx].event);
f20a35cc
PF
99 idx++;
100
101 if (verbose)
102 printf(" got event %d\n", event);
103
104 if (idx < 3)
105 send_ra(flag_event[idx].flag);
106 else
107 sd_event_exit(e, 0);
108}
109
110static void test_rs(sd_event *e) {
fa94c34b 111 usec_t time_now = now(clock_boottime_or_monotonic());
f20a35cc
PF
112 sd_icmp6_nd *nd;
113
114 if (verbose)
115 printf("* %s\n", __FUNCTION__);
116
787784c4
RC
117 assert_se(sd_icmp6_nd_new(&nd) >= 0);
118 assert_se(nd);
f20a35cc 119
787784c4 120 assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);
f20a35cc 121
787784c4
RC
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);
f20a35cc 125
787784c4 126 assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
f20a35cc
PF
127 time_now + 2 *USEC_PER_SEC, 0,
128 test_rs_hangcheck, NULL) >= 0);
129
787784c4
RC
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);
836cf090 133
787784c4 134 assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
f20a35cc
PF
135
136 sd_event_loop(e);
137
138 test_hangcheck = sd_event_source_unref(test_hangcheck);
139
140 nd = sd_icmp6_nd_unref(nd);
787784c4 141 assert_se(!nd);
f20a35cc 142
f20a35cc
PF
143 close(test_fd[1]);
144}
145
146int main(int argc, char *argv[]) {
147 sd_event *e;
148
787784c4 149 assert_se(sd_event_new(&e) >= 0);
f20a35cc
PF
150
151 log_set_max_level(LOG_DEBUG);
152 log_parse_environment();
153 log_open();
154
155 test_rs(e);
156
157 return 0;
158}