1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/in.h>
6 #include "in-addr-util.h"
10 static void test_in_addr_prefix_from_string_one(
14 const union in_addr_union
*u
,
15 unsigned char prefixlen
,
17 unsigned char prefixlen_refuse
) {
19 union in_addr_union q
;
23 r
= in_addr_prefix_from_string(p
, family
, &q
, &l
);
29 assert_se(in_addr_equal(family
, &q
, u
));
30 assert_se(l
== prefixlen
);
32 r
= in_addr_prefix_from_string_auto(p
, &f
, &q
, &l
);
35 assert_se(f
== family
);
36 assert_se(in_addr_equal(family
, &q
, u
));
37 assert_se(l
== prefixlen
);
39 r
= in_addr_prefix_from_string_auto_full(p
, PREFIXLEN_REFUSE
, &f
, &q
, &l
);
40 assert_se(r
== ret_refuse
);
43 assert_se(f
== family
);
44 assert_se(in_addr_equal(family
, &q
, u
));
45 assert_se(l
== prefixlen_refuse
);
49 TEST(in_addr_prefix_from_string
) {
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);
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);
77 static void test_in_addr_prefix_to_string_valid(int family
, const char *p
) {
78 union in_addr_union u
;
81 log_info("%s: %s", __func__
, p
);
83 assert_se(in_addr_prefix_from_string(p
, family
, &u
, &l
) >= 0);
84 ASSERT_STREQ(p
, IN_ADDR_PREFIX_TO_STRING(family
, &u
, l
));
87 static void test_in_addr_prefix_to_string_unoptimized(int family
, const char *p
) {
88 union in_addr_union u1
, u2
;
89 unsigned char len1
, len2
;
91 log_info("%s: %s", __func__
, p
);
93 assert_se(in_addr_prefix_from_string(p
, family
, &u1
, &len1
) >= 0);
94 const char *str1
= IN_ADDR_PREFIX_TO_STRING(family
, &u1
, len1
);
96 assert_se(in_addr_prefix_from_string(str1
, family
, &u2
, &len2
) >= 0);
97 const char *str2
= IN_ADDR_PREFIX_TO_STRING(family
, &u2
, len2
);
100 ASSERT_STREQ(str1
, str2
);
101 assert_se(len1
== len2
);
102 assert_se(in_addr_equal(family
, &u1
, &u2
) > 0);
105 TEST(in_addr_prefix_to_string
) {
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");
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");
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");
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");
124 TEST(in_addr_random_prefix
) {
125 _cleanup_free_
char *str
= NULL
;
126 union in_addr_union a
;
128 assert_se(in_addr_from_string(AF_INET
, "192.168.10.1", &a
) >= 0);
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"));
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."));
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);
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);
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);
155 assert_se(in_addr_from_string(AF_INET6
, "fd00::1", &a
) >= 0);
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:"));
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);
168 TEST(in_addr_is_null
) {
169 union in_addr_union i
= {};
171 assert_se(in_addr_is_null(AF_INET
, &i
) == true);
172 assert_se(in_addr_is_null(AF_INET6
, &i
) == true);
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);
178 assert_se(in_addr_is_null(-1, &i
) == -EAFNOSUPPORT
);
181 static 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
;
184 assert_se(in_addr_from_string(f
, a
, &ua
) >= 0);
185 assert_se(in_addr_from_string(f
, b
, &ub
) >= 0);
187 assert_se(in_addr_prefix_intersect(f
, &ua
, apl
, &ub
, bpl
) == result
);
190 TEST(in_addr_prefix_intersect
) {
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);
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);
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);
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);
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);
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);
216 static 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
;
219 log_debug("/* %s(%s, prefixlen=%u) */", __func__
, before
, pl
);
221 assert_se(in_addr_from_string(f
, before
, &ubefore
) >= 0);
224 assert_se((in_addr_prefix_next(f
, &t
, pl
) >= 0) == !!after
);
227 assert_se(in_addr_from_string(f
, after
, &uafter
) >= 0);
228 assert_se(in_addr_equal(f
, &t
, &uafter
) > 0);
232 TEST(in_addr_prefix_next
) {
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");
237 test_in_addr_prefix_next_one(AF_INET
, "0.0.0.0", 32, "0.0.0.1");
238 test_in_addr_prefix_next_one(AF_INET
, "255.255.255.254", 32, "255.255.255.255");
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
);
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::");
248 test_in_addr_prefix_next_one(AF_INET6
, "::", 128, "::1");
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
);
254 static 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
;
257 log_debug("/* %s(%s, prefixlen=%u, nth=%"PRIu64
") */", __func__
, before
, pl
, nth
);
259 assert_se(in_addr_from_string(f
, before
, &ubefore
) >= 0);
262 assert_se((in_addr_prefix_nth(f
, &t
, pl
, nth
) >= 0) == !!after
);
265 assert_se(in_addr_from_string(f
, after
, &uafter
) >= 0);
266 assert_se(in_addr_equal(f
, &t
, &uafter
) > 0);
270 TEST(in_addr_prefix_nth
) {
271 test_in_addr_prefix_nth_one(AF_INET
, "192.168.0.0", 24, 0, "192.168.0.0");
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");
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
);
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
);
292 test_in_addr_prefix_nth_one(AF_INET6
, "1234:5678:90ab:cdef:1234:5678:90ab:cdef", 12, 1, "1240::");
295 static void test_in_addr_prefix_range_one(
299 const char *expected_start
,
300 const char *expected_end
) {
302 union in_addr_union a
, s
, e
;
304 log_debug("/* %s(%s, prefixlen=%u) */", __func__
, in
, prefixlen
);
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
);
309 if (expected_start
) {
310 union in_addr_union es
;
312 assert_se(in_addr_from_string(family
, expected_start
, &es
) >= 0);
313 assert_se(in_addr_equal(family
, &s
, &es
) > 0);
316 union in_addr_union ee
;
318 assert_se(in_addr_from_string(family
, expected_end
, &ee
) >= 0);
319 assert_se(in_addr_equal(family
, &e
, &ee
) > 0);
323 TEST(in_addr_prefix_range
) {
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");
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");
336 static void test_in_addr_to_string_one(int f
, const char *addr
) {
337 union in_addr_union ua
;
338 _cleanup_free_
char *r
;
340 assert_se(in_addr_from_string(f
, addr
, &ua
) >= 0);
341 assert_se(in_addr_to_string(f
, &ua
, &r
) >= 0);
342 printf("%s: %s == %s\n", __func__
, addr
, r
);
343 ASSERT_STREQ(addr
, r
);
345 ASSERT_STREQ(r
, IN_ADDR_TO_STRING(f
, &ua
));
348 TEST(in_addr_to_string
) {
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::");
356 TEST(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",
369 static const char *const ipv6_netmasks
[] = {
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"
388 for (unsigned char prefixlen
= 0; prefixlen
<= 32; prefixlen
++) {
389 _cleanup_free_
char *result
= NULL
;
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
);
394 ASSERT_STREQ(ipv4_netmasks
[prefixlen
], result
);
397 for (unsigned char prefixlen
= 0; prefixlen
<= 128; prefixlen
++) {
398 _cleanup_free_
char *result
= NULL
;
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
])
404 ASSERT_STREQ(ipv6_netmasks
[prefixlen
], result
);
408 static 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
;
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
);
417 log_error("in_addr_prefix_covers_full(%s, %s)=%i (expected=%i)", prefix
, address
, r
, expected
);
418 assert_se(r
== expected
);
421 TEST(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);
431 for (unsigned i
= 0; i
<= 32; i
++) {
432 _cleanup_free_
char *prefix
= NULL
;
434 assert_se(asprintf(&prefix
, "192.168.0.128/%u", i
) >= 0);
436 for (unsigned j
= 0; j
<= 32; j
++) {
437 _cleanup_free_
char *address
= NULL
;
439 assert_se(asprintf(&address
, "192.168.0.128/%u", j
) >= 0);
440 in_addr_prefix_covers_full_one(prefix
, address
, i
<= j
);
444 for (unsigned i
= 0; i
<= 32; i
++) {
445 _cleanup_free_
char *prefix
= NULL
;
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);
451 for (unsigned i
= 0; i
<= 128; i
++) {
452 _cleanup_free_
char *prefix
= NULL
;
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);
459 DEFINE_TEST_MAIN(LOG_DEBUG
);