chiark / gitweb /
networkd: link_object_find - don't accept invalid input
[elogind.git] / src / network / test-network.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
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 "networkd.h"
23 #include "network-internal.h"
24 #include "dhcp-lease-internal.h"
25
26 static void test_deserialize_in_addr(void) {
27         _cleanup_free_ struct in_addr *addresses = NULL;
28         _cleanup_free_ struct in6_addr *addresses6 = NULL;
29         struct in_addr  a, b, c;
30         struct in6_addr d, e, f;
31         int size;
32         const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8";
33
34         assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0);
35         assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0);
36
37         assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1);
38         assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1);
39         assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1);
40         assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1);
41         assert_se(inet_pton(AF_INET6, "::1", &e) == 1);
42         assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1);
43
44         assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0);
45         assert_se(size == 3);
46         assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr)));
47         assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr)));
48         assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr)));
49
50         assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0);
51         assert_se(size == 3);
52         assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr)));
53         assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr)));
54         assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr)));
55 }
56
57 static void test_deserialize_dhcp_routes(void) {
58         size_t size, allocated;
59
60         {
61                 _cleanup_free_ struct sd_dhcp_route *routes = NULL;
62                 assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, "") >= 0);
63                 assert_se(size == 0);
64         }
65
66         {
67                 /* no errors */
68                 _cleanup_free_ struct sd_dhcp_route *routes = NULL;
69                 const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0/24,10.1.2.1 0.0.0.0/0,10.0.1.1";
70
71                 assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
72
73                 assert_se(size == 3);
74                 assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0"));
75                 assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1"));
76                 assert_se(routes[0].dst_prefixlen == 16);
77
78                 assert_se(routes[1].dst_addr.s_addr == inet_addr("10.1.2.0"));
79                 assert_se(routes[1].gw_addr.s_addr == inet_addr("10.1.2.1"));
80                 assert_se(routes[1].dst_prefixlen == 24);
81
82                 assert_se(routes[2].dst_addr.s_addr == inet_addr("0.0.0.0"));
83                 assert_se(routes[2].gw_addr.s_addr == inet_addr("10.0.1.1"));
84                 assert_se(routes[2].dst_prefixlen == 0);
85         }
86
87         {
88                 /* error in second word */
89                 _cleanup_free_ struct sd_dhcp_route *routes = NULL;
90                 const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.1";
91
92                 assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
93
94                 assert_se(size == 2);
95                 assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0"));
96                 assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1"));
97                 assert_se(routes[0].dst_prefixlen == 16);
98
99                 assert_se(routes[1].dst_addr.s_addr == inet_addr("0.0.0.0"));
100                 assert_se(routes[1].gw_addr.s_addr == inet_addr("10.0.1.1"));
101                 assert_se(routes[1].dst_prefixlen == 0);
102         }
103
104         {
105                 /* error in every word */
106                 _cleanup_free_ struct sd_dhcp_route *routes = NULL;
107                 const char *routes_string = "192.168.0.0/55,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.X";
108
109                 assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
110                 assert_se(size == 0);
111         }
112 }
113
114 static int test_load_config(Manager *manager) {
115         int r;
116 /*  TODO: should_reload, is false if the config dirs do not exist, so
117  *        so we can't do this test here, move it to a test for paths_check_timestamps
118  *        directly
119  *
120  *        assert_se(network_should_reload(manager) == true);
121 */
122
123         r = manager_load_config(manager);
124         if (r == -EPERM)
125                 return r;
126         assert_se(r >= 0);
127
128         assert_se(manager_should_reload(manager) == false);
129
130         return 0;
131 }
132
133 static void test_network_get(Manager *manager, struct udev_device *loopback) {
134         Network *network;
135         const struct ether_addr mac = {};
136
137         /* let's assume that the test machine does not have a .network file
138            that applies to the loopback device... */
139         assert_se(network_get(manager, loopback, "lo", &mac, &network) == -ENOENT);
140         assert_se(!network);
141 }
142
143 static void test_address_equality(void) {
144         _cleanup_address_free_ Address *a1 = NULL, *a2 = NULL;
145
146         assert_se(address_new_dynamic(&a1) >= 0);
147         assert_se(address_new_dynamic(&a2) >= 0);
148
149         assert_se(address_equal(NULL, NULL));
150         assert_se(!address_equal(a1, NULL));
151         assert_se(!address_equal(NULL, a2));
152         assert_se(address_equal(a1, a2));
153
154         a1->family = AF_INET;
155         assert_se(!address_equal(a1, a2));
156
157         a2->family = AF_INET;
158         assert_se(address_equal(a1, a2));
159
160         assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in));
161         assert_se(address_equal(a1, a2));
162         assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in));
163         assert_se(address_equal(a1, a2));
164         a1->prefixlen = 10;
165         assert_se(!address_equal(a1, a2));
166         a2->prefixlen = 10;
167         assert_se(address_equal(a1, a2));
168
169         assert_se(inet_pton(AF_INET, "192.168.3.10", &a2->in_addr.in));
170         assert_se(address_equal(a1, a2));
171
172         a1->family = AF_INET6;
173         assert_se(!address_equal(a1, a2));
174
175         a2->family = AF_INET6;
176         assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6));
177         assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6));
178         assert_se(address_equal(a1, a2));
179
180         a2->prefixlen = 8;
181         assert_se(address_equal(a1, a2));
182
183         assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6));
184         assert_se(!address_equal(a1, a2));
185 }
186
187 int main(void) {
188         _cleanup_manager_free_ Manager *manager = NULL;
189         struct udev *udev;
190         struct udev_device *loopback;
191         int r;
192
193         test_deserialize_in_addr();
194         test_deserialize_dhcp_routes();
195         test_address_equality();
196
197         assert_se(manager_new(&manager) >= 0);
198
199         r = test_load_config(manager);
200         if (r == -EPERM)
201                 return EXIT_TEST_SKIP;
202
203         udev = udev_new();
204         assert_se(udev);
205
206         loopback = udev_device_new_from_syspath(udev, "/sys/class/net/lo");
207         assert_se(loopback);
208         assert_se(udev_device_get_ifindex(loopback) == 1);
209
210         test_network_get(manager, loopback);
211
212         assert_se(manager_rtnl_enumerate_links(manager) >= 0);
213
214         udev_device_unref(loopback);
215         udev_unref(udev);
216 }