]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-in-addr-util.c
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
[thirdparty/systemd.git] / src / test / test-in-addr-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
f4912f3a 2
e762ea74 3#include <fnmatch.h>
f4912f3a
LP
4#include <netinet/in.h>
5
6#include "in-addr-util.h"
0bc311bb
YW
7#include "strv.h"
8#include "tests.h"
f4912f3a 9
146cf7f0 10static void test_in_addr_prefix_from_string_one(
9e0fdc21
YW
11 const char *p,
12 int family,
13 int ret,
14 const union in_addr_union *u,
15 unsigned char prefixlen,
16 int ret_refuse,
34023570 17 unsigned char prefixlen_refuse) {
9e0fdc21 18
f4912f3a
LP
19 union in_addr_union q;
20 unsigned char l;
9e0fdc21 21 int f, r;
f4912f3a 22
9e0fdc21 23 r = in_addr_prefix_from_string(p, family, &q, &l);
f4912f3a
LP
24 assert_se(r == ret);
25
9e0fdc21
YW
26 if (r < 0)
27 return;
28
29 assert_se(in_addr_equal(family, &q, u));
30 assert_se(l == prefixlen);
31
32 r = in_addr_prefix_from_string_auto(p, &f, &q, &l);
33 assert_se(r >= 0);
34
35 assert_se(f == family);
36 assert_se(in_addr_equal(family, &q, u));
37 assert_se(l == prefixlen);
38
c1316cd0 39 r = in_addr_prefix_from_string_auto_full(p, PREFIXLEN_REFUSE, &f, &q, &l);
9e0fdc21 40 assert_se(r == ret_refuse);
f4912f3a 41
9e0fdc21
YW
42 if (r >= 0) {
43 assert_se(f == family);
f4912f3a 44 assert_se(in_addr_equal(family, &q, u));
9e0fdc21
YW
45 assert_se(l == prefixlen_refuse);
46 }
f4912f3a
LP
47}
48
4f7452a8 49TEST(in_addr_prefix_from_string) {
34023570
YW
50 test_in_addr_prefix_from_string_one("", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0);
51 test_in_addr_prefix_from_string_one("/", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0);
52 test_in_addr_prefix_from_string_one("/8", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0);
53 test_in_addr_prefix_from_string_one("1.2.3.4", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, -ENOANO, 0);
54 test_in_addr_prefix_from_string_one("1.2.3.4/0", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 0, 0, 0);
55 test_in_addr_prefix_from_string_one("1.2.3.4/1", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 1, 0, 1);
56 test_in_addr_prefix_from_string_one("1.2.3.4/2", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 2, 0, 2);
57 test_in_addr_prefix_from_string_one("1.2.3.4/32", AF_INET, 0, &(union in_addr_union) { .in = (struct in_addr) { .s_addr = htobe32(0x01020304) } }, 32, 0, 32);
58 test_in_addr_prefix_from_string_one("1.2.3.4/33", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0);
59 test_in_addr_prefix_from_string_one("1.2.3.4/-1", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0);
60 test_in_addr_prefix_from_string_one("::1", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0);
61
62 test_in_addr_prefix_from_string_one("", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0);
63 test_in_addr_prefix_from_string_one("/", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0);
64 test_in_addr_prefix_from_string_one("/8", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0);
65 test_in_addr_prefix_from_string_one("::1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, -ENOANO, 0);
66 test_in_addr_prefix_from_string_one("::1/0", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, 0, 0);
67 test_in_addr_prefix_from_string_one("::1/1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 1, 0, 1);
68 test_in_addr_prefix_from_string_one("::1/2", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 2, 0, 2);
69 test_in_addr_prefix_from_string_one("::1/32", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 32, 0, 32);
70 test_in_addr_prefix_from_string_one("::1/33", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 33, 0, 33);
71 test_in_addr_prefix_from_string_one("::1/64", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 64, 0, 64);
72 test_in_addr_prefix_from_string_one("::1/128", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, 0, 128);
73 test_in_addr_prefix_from_string_one("::1/129", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0);
74 test_in_addr_prefix_from_string_one("::1/-1", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0);
146cf7f0
YW
75}
76
9201eea1 77static void test_in_addr_prefix_to_string_valid(int family, const char *p) {
9201eea1
YW
78 union in_addr_union u;
79 unsigned char l;
80
38c30b35 81 log_info("%s: %s", __func__, p);
9201eea1
YW
82
83 assert_se(in_addr_prefix_from_string(p, family, &u, &l) >= 0);
c79e88b3 84 ASSERT_STREQ(p, IN_ADDR_PREFIX_TO_STRING(family, &u, l));
9201eea1
YW
85}
86
87static void test_in_addr_prefix_to_string_unoptimized(int family, const char *p) {
9201eea1
YW
88 union in_addr_union u1, u2;
89 unsigned char len1, len2;
90
38c30b35 91 log_info("%s: %s", __func__, p);
9201eea1
YW
92
93 assert_se(in_addr_prefix_from_string(p, family, &u1, &len1) >= 0);
c71384a9
ZJS
94 const char *str1 = IN_ADDR_PREFIX_TO_STRING(family, &u1, len1);
95 assert_se(str1);
9201eea1 96 assert_se(in_addr_prefix_from_string(str1, family, &u2, &len2) >= 0);
c71384a9
ZJS
97 const char *str2 = IN_ADDR_PREFIX_TO_STRING(family, &u2, len2);
98 assert_se(str2);
9201eea1 99
c79e88b3 100 ASSERT_STREQ(str1, str2);
9201eea1
YW
101 assert_se(len1 == len2);
102 assert_se(in_addr_equal(family, &u1, &u2) > 0);
103}
104
4f7452a8 105TEST(in_addr_prefix_to_string) {
9201eea1
YW
106 test_in_addr_prefix_to_string_valid(AF_INET, "0.0.0.0/32");
107 test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/0");
108 test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/24");
109 test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/32");
110 test_in_addr_prefix_to_string_valid(AF_INET, "255.255.255.255/32");
111
112 test_in_addr_prefix_to_string_valid(AF_INET6, "::1/128");
113 test_in_addr_prefix_to_string_valid(AF_INET6, "fd00:abcd::1/64");
114 test_in_addr_prefix_to_string_valid(AF_INET6, "fd00:abcd::1234:1/64");
115 test_in_addr_prefix_to_string_valid(AF_INET6, "1111:2222:3333:4444:5555:6666:7777:8888/128");
116
117 test_in_addr_prefix_to_string_unoptimized(AF_INET, "0.0.0.0");
118 test_in_addr_prefix_to_string_unoptimized(AF_INET, "192.168.0.1");
119
120 test_in_addr_prefix_to_string_unoptimized(AF_INET6, "fd00:0000:0000:0000:0000:0000:0000:0001/64");
121 test_in_addr_prefix_to_string_unoptimized(AF_INET6, "fd00:1111::0000:2222:3333:4444:0001/64");
122}
123
4f7452a8 124TEST(in_addr_random_prefix) {
e762ea74
YW
125 _cleanup_free_ char *str = NULL;
126 union in_addr_union a;
127
128 assert_se(in_addr_from_string(AF_INET, "192.168.10.1", &a) >= 0);
129
130 assert_se(in_addr_random_prefix(AF_INET, &a, 31, 32) >= 0);
131 assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0);
132 assert_se(STR_IN_SET(str, "192.168.10.0", "192.168.10.1"));
133 str = mfree(str);
134
135 assert_se(in_addr_random_prefix(AF_INET, &a, 24, 26) >= 0);
136 assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0);
137 assert_se(startswith(str, "192.168.10."));
138 str = mfree(str);
139
140 assert_se(in_addr_random_prefix(AF_INET, &a, 16, 24) >= 0);
141 assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0);
142 assert_se(fnmatch("192.168.[0-9]*.0", str, 0) == 0);
143 str = mfree(str);
144
145 assert_se(in_addr_random_prefix(AF_INET, &a, 8, 24) >= 0);
146 assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0);
147 assert_se(fnmatch("192.[0-9]*.[0-9]*.0", str, 0) == 0);
148 str = mfree(str);
149
150 assert_se(in_addr_random_prefix(AF_INET, &a, 8, 16) >= 0);
151 assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0);
152 assert_se(fnmatch("192.[0-9]*.0.0", str, 0) == 0);
153 str = mfree(str);
154
155 assert_se(in_addr_from_string(AF_INET6, "fd00::1", &a) >= 0);
156
157 assert_se(in_addr_random_prefix(AF_INET6, &a, 16, 64) >= 0);
158 assert_se(in_addr_to_string(AF_INET6, &a, &str) >= 0);
159 assert_se(startswith(str, "fd00:"));
160 str = mfree(str);
161
162 assert_se(in_addr_random_prefix(AF_INET6, &a, 8, 16) >= 0);
163 assert_se(in_addr_to_string(AF_INET6, &a, &str) >= 0);
164 assert_se(fnmatch("fd??::", str, 0) == 0);
165 str = mfree(str);
166}
167
4f7452a8 168TEST(in_addr_is_null) {
23c5aeaa
YW
169 union in_addr_union i = {};
170
23c5aeaa
YW
171 assert_se(in_addr_is_null(AF_INET, &i) == true);
172 assert_se(in_addr_is_null(AF_INET6, &i) == true);
173
174 i.in.s_addr = 0x1000000;
175 assert_se(in_addr_is_null(AF_INET, &i) == false);
176 assert_se(in_addr_is_null(AF_INET6, &i) == false);
177
178 assert_se(in_addr_is_null(-1, &i) == -EAFNOSUPPORT);
179}
180
181static void test_in_addr_prefix_intersect_one(unsigned f, const char *a, unsigned apl, const char *b, unsigned bpl, int result) {
182 union in_addr_union ua, ub;
183
184 assert_se(in_addr_from_string(f, a, &ua) >= 0);
185 assert_se(in_addr_from_string(f, b, &ub) >= 0);
186
187 assert_se(in_addr_prefix_intersect(f, &ua, apl, &ub, bpl) == result);
188}
189
4f7452a8 190TEST(in_addr_prefix_intersect) {
23c5aeaa
YW
191 test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 32, "255.255.255.254", 32, 0);
192 test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 0, "255.255.255.255", 32, 1);
193 test_in_addr_prefix_intersect_one(AF_INET, "0.0.0.0", 0, "47.11.8.15", 32, 1);
194
195 test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.1", 24, 1);
196 test_in_addr_prefix_intersect_one(AF_INET, "2.2.2.2", 24, "1.1.1.1", 24, 0);
197
198 test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 25, 1);
199 test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 26, 1);
200 test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.127", 25, 1);
201 test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.255", 25, 0);
202
203 test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 128, 0);
204 test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1);
205 test_in_addr_prefix_intersect_one(AF_INET6, "::", 0, "beef:beef:beef:beef:beef:beef:beef:beef", 128, 1);
206
207 test_in_addr_prefix_intersect_one(AF_INET6, "1::2", 64, "1::2", 64, 1);
208 test_in_addr_prefix_intersect_one(AF_INET6, "2::2", 64, "1::2", 64, 0);
209
210 test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 121, 1);
211 test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 122, 1);
212 test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::007f", 121, 1);
213 test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::00ff", 121, 0);
214}
215
216static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) {
217 union in_addr_union ubefore, uafter, t;
218
0bc311bb 219 log_debug("/* %s(%s, prefixlen=%u) */", __func__, before, pl);
9164338b 220
23c5aeaa
YW
221 assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
222
223 t = ubefore;
518b6da5 224 assert_se((in_addr_prefix_next(f, &t, pl) >= 0) == !!after);
23c5aeaa
YW
225
226 if (after) {
227 assert_se(in_addr_from_string(f, after, &uafter) >= 0);
228 assert_se(in_addr_equal(f, &t, &uafter) > 0);
229 }
230}
231
4f7452a8 232TEST(in_addr_prefix_next) {
23c5aeaa
YW
233 test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0");
234 test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0");
235 test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0");
236
237 test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1");
9164338b 238 test_in_addr_prefix_next_one(AF_INET, "255.255.255.254", 32, "255.255.255.255");
23c5aeaa
YW
239 test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL);
240 test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL);
241
242 test_in_addr_prefix_next_one(AF_INET6, "4400::", 128, "4400::0001");
243 test_in_addr_prefix_next_one(AF_INET6, "4400::", 120, "4400::0100");
244 test_in_addr_prefix_next_one(AF_INET6, "4400::", 127, "4400::0002");
245 test_in_addr_prefix_next_one(AF_INET6, "4400::", 8, "4500::");
246 test_in_addr_prefix_next_one(AF_INET6, "4400::", 7, "4600::");
247
248 test_in_addr_prefix_next_one(AF_INET6, "::", 128, "::1");
249
250 test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, NULL);
251 test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00", 120, NULL);
252}
253
254static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned pl, uint64_t nth, const char *after) {
255 union in_addr_union ubefore, uafter, t;
256
0bc311bb 257 log_debug("/* %s(%s, prefixlen=%u, nth=%"PRIu64") */", __func__, before, pl, nth);
9164338b 258
23c5aeaa
YW
259 assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
260
261 t = ubefore;
518b6da5 262 assert_se((in_addr_prefix_nth(f, &t, pl, nth) >= 0) == !!after);
23c5aeaa
YW
263
264 if (after) {
265 assert_se(in_addr_from_string(f, after, &uafter) >= 0);
266 assert_se(in_addr_equal(f, &t, &uafter) > 0);
267 }
268}
269
4f7452a8 270TEST(in_addr_prefix_nth) {
23c5aeaa 271 test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 0, "192.168.0.0");
9164338b
YW
272 test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 0, "192.168.0.0");
273 test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 1, "192.168.1.0");
23c5aeaa
YW
274 test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 4, "192.168.4.0");
275 test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 25, 1, "192.168.0.128");
276 test_in_addr_prefix_nth_one(AF_INET, "192.168.255.0", 25, 1, "192.168.255.128");
277 test_in_addr_prefix_nth_one(AF_INET, "192.168.255.0", 24, 0, "192.168.255.0");
278 test_in_addr_prefix_nth_one(AF_INET, "255.255.255.255", 32, 1, NULL);
279 test_in_addr_prefix_nth_one(AF_INET, "255.255.255.255", 0, 1, NULL);
280
281 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 8, 1, "4500::");
282 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 7, 1, "4600::");
283 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 64, 1, "4400:0:0:1::");
284 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 64, 2, "4400:0:0:2::");
285 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 64, 0xbad, "4400:0:0:0bad::");
286 test_in_addr_prefix_nth_one(AF_INET6, "4400:0:0:ffff::", 64, 1, "4400:0:1::");
287 test_in_addr_prefix_nth_one(AF_INET6, "4400::", 56, ((uint64_t)1<<48) -1, "44ff:ffff:ffff:ff00::");
288 test_in_addr_prefix_nth_one(AF_INET6, "0000::", 8, 255, "ff00::");
289 test_in_addr_prefix_nth_one(AF_INET6, "0000::", 8, 256, NULL);
290 test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1, NULL);
291 test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, 1, NULL);
9164338b 292 test_in_addr_prefix_nth_one(AF_INET6, "1234:5678:90ab:cdef:1234:5678:90ab:cdef", 12, 1, "1240::");
23c5aeaa
YW
293}
294
1534c579
YW
295static void test_in_addr_prefix_range_one(
296 int family,
297 const char *in,
298 unsigned prefixlen,
299 const char *expected_start,
300 const char *expected_end) {
301
302 union in_addr_union a, s, e;
303
0bc311bb 304 log_debug("/* %s(%s, prefixlen=%u) */", __func__, in, prefixlen);
1534c579
YW
305
306 assert_se(in_addr_from_string(family, in, &a) >= 0);
307 assert_se((in_addr_prefix_range(family, &a, prefixlen, &s, &e) >= 0) == !!expected_start);
308
309 if (expected_start) {
310 union in_addr_union es;
311
312 assert_se(in_addr_from_string(family, expected_start, &es) >= 0);
313 assert_se(in_addr_equal(family, &s, &es) > 0);
314 }
315 if (expected_end) {
316 union in_addr_union ee;
317
318 assert_se(in_addr_from_string(family, expected_end, &ee) >= 0);
319 assert_se(in_addr_equal(family, &e, &ee) > 0);
320 }
321}
322
4f7452a8 323TEST(in_addr_prefix_range) {
1534c579
YW
324 test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 24, "192.168.123.0", "192.168.124.0");
325 test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 16, "192.168.0.0", "192.169.0.0");
326
327 test_in_addr_prefix_range_one(AF_INET6, "dead:beef::", 64, "dead:beef::", "dead:beef:0:1::");
328 test_in_addr_prefix_range_one(AF_INET6, "dead:0:0:beef::", 64, "dead:0:0:beef::", "dead:0:0:bef0::");
329 test_in_addr_prefix_range_one(AF_INET6, "2001::", 48, "2001::", "2001:0:1::");
330 test_in_addr_prefix_range_one(AF_INET6, "2001::", 56, "2001::", "2001:0:0:0100::");
331 test_in_addr_prefix_range_one(AF_INET6, "2001::", 65, "2001::", "2001::8000:0:0:0");
332 test_in_addr_prefix_range_one(AF_INET6, "2001::", 66, "2001::", "2001::4000:0:0:0");
333 test_in_addr_prefix_range_one(AF_INET6, "2001::", 127, "2001::", "2001::2");
334}
335
23c5aeaa
YW
336static void test_in_addr_to_string_one(int f, const char *addr) {
337 union in_addr_union ua;
84dbb3fd 338 _cleanup_free_ char *r;
23c5aeaa
YW
339
340 assert_se(in_addr_from_string(f, addr, &ua) >= 0);
341 assert_se(in_addr_to_string(f, &ua, &r) >= 0);
61af1813 342 printf("%s: %s == %s\n", __func__, addr, r);
c79e88b3 343 ASSERT_STREQ(addr, r);
84dbb3fd 344
c79e88b3 345 ASSERT_STREQ(r, IN_ADDR_TO_STRING(f, &ua));
23c5aeaa
YW
346}
347
4f7452a8 348TEST(in_addr_to_string) {
23c5aeaa
YW
349 test_in_addr_to_string_one(AF_INET, "192.168.0.1");
350 test_in_addr_to_string_one(AF_INET, "10.11.12.13");
351 test_in_addr_to_string_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
352 test_in_addr_to_string_one(AF_INET6, "::1");
353 test_in_addr_to_string_one(AF_INET6, "fe80::");
354}
355
3f36b9ed
TM
356TEST(in_addr_prefixlen_to_netmask) {
357 union in_addr_union addr;
358 static const char *const ipv4_netmasks[] = {
359 "0.0.0.0", "128.0.0.0", "192.0.0.0", "224.0.0.0", "240.0.0.0",
360 "248.0.0.0", "252.0.0.0", "254.0.0.0", "255.0.0.0",
361 "255.128.0.0", "255.192.0.0", "255.224.0.0", "255.240.0.0",
362 "255.248.0.0", "255.252.0.0", "255.254.0.0", "255.255.0.0",
363 "255.255.128.0", "255.255.192.0", "255.255.224.0", "255.255.240.0",
364 "255.255.248.0", "255.255.252.0", "255.255.254.0", "255.255.255.0",
365 "255.255.255.128", "255.255.255.192", "255.255.255.224", "255.255.255.240",
366 "255.255.255.248", "255.255.255.252", "255.255.255.254", "255.255.255.255",
367 };
368
369 static const char *const ipv6_netmasks[] = {
370 [0] = "::",
371 [1] = "8000::",
372 [2] = "c000::",
373 [7] = "fe00::",
374 [8] = "ff00::",
375 [9] = "ff80::",
376 [16] = "ffff::",
377 [17] = "ffff:8000::",
378 [32] = "ffff:ffff::",
379 [33] = "ffff:ffff:8000::",
380 [64] = "ffff:ffff:ffff:ffff::",
381 [65] = "ffff:ffff:ffff:ffff:8000::",
382 [96] = "ffff:ffff:ffff:ffff:ffff:ffff::",
383 [97] = "ffff:ffff:ffff:ffff:ffff:ffff:8000:0",
384 [127] = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe",
385 [128] = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
386 };
387
388 for (unsigned char prefixlen = 0; prefixlen <= 32; prefixlen++) {
389 _cleanup_free_ char *result = NULL;
390
391 assert_se(in_addr_prefixlen_to_netmask(AF_INET, &addr, prefixlen) >= 0);
392 assert_se(in_addr_to_string(AF_INET, &addr, &result) >= 0);
393 printf("test_in_addr_prefixlen_to_netmask: %s == %s\n", ipv4_netmasks[prefixlen], result);
c79e88b3 394 ASSERT_STREQ(ipv4_netmasks[prefixlen], result);
3f36b9ed
TM
395 }
396
397 for (unsigned char prefixlen = 0; prefixlen <= 128; prefixlen++) {
398 _cleanup_free_ char *result = NULL;
399
400 assert_se(in_addr_prefixlen_to_netmask(AF_INET6, &addr, prefixlen) >= 0);
401 assert_se(in_addr_to_string(AF_INET6, &addr, &result) >= 0);
402 printf("test_in_addr_prefixlen_to_netmask: %s\n", result);
403 if (ipv6_netmasks[prefixlen])
c79e88b3 404 ASSERT_STREQ(ipv6_netmasks[prefixlen], result);
3f36b9ed
TM
405 }
406}
407
4591efff
YW
408static void in_addr_prefix_covers_full_one(const char *prefix, const char *address, int expected) {
409 union in_addr_union p, a;
410 unsigned char plen, alen;
411 int family, r;
412
413 assert_se(in_addr_prefix_from_string_auto(prefix, &family, &p, &plen) >= 0);
414 assert_se(in_addr_prefix_from_string(address, family, &a, &alen) >= 0);
415 r = in_addr_prefix_covers_full(family, &p, plen, &a, alen);
416 if (r != expected)
417 log_error("in_addr_prefix_covers_full(%s, %s)=%i (expected=%i)", prefix, address, r, expected);
418 assert_se(r == expected);
419}
420
421TEST(in_addr_prefix_covers_full) {
422 /* From issue #32715. */
423 in_addr_prefix_covers_full_one("192.168.235.129/32", "192.168.0.128/32", 0);
424 in_addr_prefix_covers_full_one("192.168.235.130/32", "192.168.0.128/32", 0);
425 in_addr_prefix_covers_full_one("169.254.0.0/17", "192.168.0.128/32", 0);
426 in_addr_prefix_covers_full_one("169.254.128.0/17", "192.168.0.128/32", 0);
427 in_addr_prefix_covers_full_one("0.0.0.0/1", "192.168.0.128/32", 0);
428 in_addr_prefix_covers_full_one("128.0.0.0/1", "192.168.0.128/32", 1);
429 in_addr_prefix_covers_full_one("0.0.0.0/0", "192.168.0.128/32", 1);
430
431 for (unsigned i = 0; i <= 32; i++) {
432 _cleanup_free_ char *prefix = NULL;
433
434 assert_se(asprintf(&prefix, "192.168.0.128/%u", i) >= 0);
435
436 for (unsigned j = 0; j <= 32; j++) {
437 _cleanup_free_ char *address = NULL;
438
439 assert_se(asprintf(&address, "192.168.0.128/%u", j) >= 0);
440 in_addr_prefix_covers_full_one(prefix, address, i <= j);
441 }
442 }
443
444 for (unsigned i = 0; i <= 32; i++) {
445 _cleanup_free_ char *prefix = NULL;
446
447 assert_se(asprintf(&prefix, "192.168.235.129/%u", i) >= 0);
448 in_addr_prefix_covers_full_one(prefix, "192.168.0.128/32", i <= 16);
449 }
450
451 for (unsigned i = 0; i <= 128; i++) {
452 _cleanup_free_ char *prefix = NULL;
453
454 assert_se(asprintf(&prefix, "dead:beef::/%u", i) >= 0);
455 in_addr_prefix_covers_full_one(prefix, "dead:0:beef::1/128", i <= 16);
456 }
457}
458
4f7452a8 459DEFINE_TEST_MAIN(LOG_DEBUG);