]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
f4912f3a | 2 | |
e762ea74 | 3 | #include <fnmatch.h> |
f4912f3a LP |
4 | #include <netinet/in.h> |
5 | ||
9e0fdc21 | 6 | #include "log.h" |
e762ea74 | 7 | #include "strv.h" |
f4912f3a LP |
8 | #include "in-addr-util.h" |
9 | ||
146cf7f0 | 10 | static 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, | |
17 | unsigned char prefixlen_refuse, | |
18 | int ret_legacy, | |
19 | unsigned char prefixlen_legacy) { | |
20 | ||
f4912f3a LP |
21 | union in_addr_union q; |
22 | unsigned char l; | |
9e0fdc21 | 23 | int f, r; |
f4912f3a | 24 | |
9e0fdc21 | 25 | r = in_addr_prefix_from_string(p, family, &q, &l); |
f4912f3a LP |
26 | assert_se(r == ret); |
27 | ||
9e0fdc21 YW |
28 | if (r < 0) |
29 | return; | |
30 | ||
31 | assert_se(in_addr_equal(family, &q, u)); | |
32 | assert_se(l == prefixlen); | |
33 | ||
34 | r = in_addr_prefix_from_string_auto(p, &f, &q, &l); | |
35 | assert_se(r >= 0); | |
36 | ||
37 | assert_se(f == family); | |
38 | assert_se(in_addr_equal(family, &q, u)); | |
39 | assert_se(l == prefixlen); | |
40 | ||
41 | r = in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_REFUSE, &f, &q, &l); | |
42 | assert_se(r == ret_refuse); | |
f4912f3a | 43 | |
9e0fdc21 YW |
44 | if (r >= 0) { |
45 | assert_se(f == family); | |
f4912f3a | 46 | assert_se(in_addr_equal(family, &q, u)); |
9e0fdc21 YW |
47 | assert_se(l == prefixlen_refuse); |
48 | } | |
f4912f3a | 49 | |
9e0fdc21 YW |
50 | r = in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_LEGACY, &f, &q, &l); |
51 | assert_se(r == ret_legacy); | |
f4912f3a | 52 | |
9e0fdc21 | 53 | if (r >= 0) { |
f4912f3a LP |
54 | assert_se(f == family); |
55 | assert_se(in_addr_equal(family, &q, u)); | |
9e0fdc21 | 56 | assert_se(l == prefixlen_legacy); |
f4912f3a LP |
57 | } |
58 | } | |
59 | ||
146cf7f0 YW |
60 | static void test_in_addr_prefix_from_string(void) { |
61 | test_in_addr_prefix_from_string_one("", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
62 | test_in_addr_prefix_from_string_one("/", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
63 | test_in_addr_prefix_from_string_one("/8", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
64 | 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, 0, 8); | |
65 | 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, 0, 0); | |
66 | 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, 0, 1); | |
67 | 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, 0, 2); | |
68 | 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, 0, 32); | |
69 | test_in_addr_prefix_from_string_one("1.2.3.4/33", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0); | |
70 | test_in_addr_prefix_from_string_one("1.2.3.4/-1", AF_INET, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0); | |
71 | test_in_addr_prefix_from_string_one("::1", AF_INET, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
72 | ||
73 | test_in_addr_prefix_from_string_one("", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
74 | test_in_addr_prefix_from_string_one("/", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
75 | test_in_addr_prefix_from_string_one("/8", AF_INET6, -EINVAL, NULL, 0, -EINVAL, 0, -EINVAL, 0); | |
76 | test_in_addr_prefix_from_string_one("::1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, -ENOANO, 0, 0, 0); | |
77 | test_in_addr_prefix_from_string_one("::1/0", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 0, 0, 0, 0, 0); | |
78 | test_in_addr_prefix_from_string_one("::1/1", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 1, 0, 1, 0, 1); | |
79 | test_in_addr_prefix_from_string_one("::1/2", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 2, 0, 2, 0, 2); | |
80 | test_in_addr_prefix_from_string_one("::1/32", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 32, 0, 32, 0, 32); | |
81 | test_in_addr_prefix_from_string_one("::1/33", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 33, 0, 33, 0, 33); | |
82 | test_in_addr_prefix_from_string_one("::1/64", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 64, 0, 64, 0, 64); | |
83 | test_in_addr_prefix_from_string_one("::1/128", AF_INET6, 0, &(union in_addr_union) { .in6 = IN6ADDR_LOOPBACK_INIT }, 128, 0, 128, 0, 128); | |
84 | test_in_addr_prefix_from_string_one("::1/129", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0); | |
85 | test_in_addr_prefix_from_string_one("::1/-1", AF_INET6, -ERANGE, NULL, 0, -ERANGE, 0, -ERANGE, 0); | |
86 | } | |
87 | ||
9201eea1 YW |
88 | static void test_in_addr_prefix_to_string_valid(int family, const char *p) { |
89 | _cleanup_free_ char *str = NULL; | |
90 | union in_addr_union u; | |
91 | unsigned char l; | |
92 | ||
93 | log_info("/* %s */", p); | |
94 | ||
95 | assert_se(in_addr_prefix_from_string(p, family, &u, &l) >= 0); | |
96 | assert_se(in_addr_prefix_to_string(family, &u, l, &str) >= 0); | |
97 | assert_se(streq(str, p)); | |
98 | } | |
99 | ||
100 | static void test_in_addr_prefix_to_string_unoptimized(int family, const char *p) { | |
101 | _cleanup_free_ char *str1 = NULL, *str2 = NULL; | |
102 | union in_addr_union u1, u2; | |
103 | unsigned char len1, len2; | |
104 | ||
105 | log_info("/* %s */", p); | |
106 | ||
107 | assert_se(in_addr_prefix_from_string(p, family, &u1, &len1) >= 0); | |
108 | assert_se(in_addr_prefix_to_string(family, &u1, len1, &str1) >= 0); | |
109 | assert_se(in_addr_prefix_from_string(str1, family, &u2, &len2) >= 0); | |
110 | assert_se(in_addr_prefix_to_string(family, &u2, len2, &str2) >= 0); | |
111 | ||
112 | assert_se(streq(str1, str2)); | |
113 | assert_se(len1 == len2); | |
114 | assert_se(in_addr_equal(family, &u1, &u2) > 0); | |
115 | } | |
116 | ||
117 | static void test_in_addr_prefix_to_string(void) { | |
118 | test_in_addr_prefix_to_string_valid(AF_INET, "0.0.0.0/32"); | |
119 | test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/0"); | |
120 | test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/24"); | |
121 | test_in_addr_prefix_to_string_valid(AF_INET, "1.2.3.4/32"); | |
122 | test_in_addr_prefix_to_string_valid(AF_INET, "255.255.255.255/32"); | |
123 | ||
124 | test_in_addr_prefix_to_string_valid(AF_INET6, "::1/128"); | |
125 | test_in_addr_prefix_to_string_valid(AF_INET6, "fd00:abcd::1/64"); | |
126 | test_in_addr_prefix_to_string_valid(AF_INET6, "fd00:abcd::1234:1/64"); | |
127 | test_in_addr_prefix_to_string_valid(AF_INET6, "1111:2222:3333:4444:5555:6666:7777:8888/128"); | |
128 | ||
129 | test_in_addr_prefix_to_string_unoptimized(AF_INET, "0.0.0.0"); | |
130 | test_in_addr_prefix_to_string_unoptimized(AF_INET, "192.168.0.1"); | |
131 | ||
132 | test_in_addr_prefix_to_string_unoptimized(AF_INET6, "fd00:0000:0000:0000:0000:0000:0000:0001/64"); | |
133 | test_in_addr_prefix_to_string_unoptimized(AF_INET6, "fd00:1111::0000:2222:3333:4444:0001/64"); | |
134 | } | |
135 | ||
e762ea74 YW |
136 | static void test_in_addr_random_prefix(void) { |
137 | _cleanup_free_ char *str = NULL; | |
138 | union in_addr_union a; | |
139 | ||
140 | assert_se(in_addr_from_string(AF_INET, "192.168.10.1", &a) >= 0); | |
141 | ||
142 | assert_se(in_addr_random_prefix(AF_INET, &a, 31, 32) >= 0); | |
143 | assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0); | |
144 | assert_se(STR_IN_SET(str, "192.168.10.0", "192.168.10.1")); | |
145 | str = mfree(str); | |
146 | ||
147 | assert_se(in_addr_random_prefix(AF_INET, &a, 24, 26) >= 0); | |
148 | assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0); | |
149 | assert_se(startswith(str, "192.168.10.")); | |
150 | str = mfree(str); | |
151 | ||
152 | assert_se(in_addr_random_prefix(AF_INET, &a, 16, 24) >= 0); | |
153 | assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0); | |
154 | assert_se(fnmatch("192.168.[0-9]*.0", str, 0) == 0); | |
155 | str = mfree(str); | |
156 | ||
157 | assert_se(in_addr_random_prefix(AF_INET, &a, 8, 24) >= 0); | |
158 | assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0); | |
159 | assert_se(fnmatch("192.[0-9]*.[0-9]*.0", str, 0) == 0); | |
160 | str = mfree(str); | |
161 | ||
162 | assert_se(in_addr_random_prefix(AF_INET, &a, 8, 16) >= 0); | |
163 | assert_se(in_addr_to_string(AF_INET, &a, &str) >= 0); | |
164 | assert_se(fnmatch("192.[0-9]*.0.0", str, 0) == 0); | |
165 | str = mfree(str); | |
166 | ||
167 | assert_se(in_addr_from_string(AF_INET6, "fd00::1", &a) >= 0); | |
168 | ||
169 | assert_se(in_addr_random_prefix(AF_INET6, &a, 16, 64) >= 0); | |
170 | assert_se(in_addr_to_string(AF_INET6, &a, &str) >= 0); | |
171 | assert_se(startswith(str, "fd00:")); | |
172 | str = mfree(str); | |
173 | ||
174 | assert_se(in_addr_random_prefix(AF_INET6, &a, 8, 16) >= 0); | |
175 | assert_se(in_addr_to_string(AF_INET6, &a, &str) >= 0); | |
176 | assert_se(fnmatch("fd??::", str, 0) == 0); | |
177 | str = mfree(str); | |
178 | } | |
179 | ||
f4912f3a | 180 | int main(int argc, char *argv[]) { |
146cf7f0 | 181 | test_in_addr_prefix_from_string(); |
e762ea74 | 182 | test_in_addr_random_prefix(); |
9201eea1 | 183 | test_in_addr_prefix_to_string(); |
e762ea74 | 184 | |
f4912f3a LP |
185 | return 0; |
186 | } |