]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-dns-domain.c
Merge pull request #2003 from eworm-de/virt
[thirdparty/systemd.git] / src / test / test-dns-domain.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
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
b5efdb8a 22#include "alloc-util.h"
4ad7f276 23#include "dns-domain.h"
07630cea
LP
24#include "macro.h"
25#include "string-util.h"
74b2466e
LP
26
27static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
28 char buffer[buffer_sz];
29 int r;
30
31 r = dns_label_unescape(&what, buffer, buffer_sz);
32 assert_se(r == ret);
33
34 if (r < 0)
35 return;
36
37 assert_se(streq(buffer, expect));
38}
39
40static void test_dns_label_unescape(void) {
41 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
42 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
43 test_dns_label_unescape_one("", "", 10, 0);
44 test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
45 test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
46 test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
47 test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
48 test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7);
49 test_dns_label_unescape_one(".", "", 20, 0);
50 test_dns_label_unescape_one("..", "", 20, -EINVAL);
51 test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
52 test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
53}
54
54adabf7
BG
55static void test_dns_name_to_wire_format_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
56 uint8_t buffer[buffer_sz];
57 int r;
58
59 r = dns_name_to_wire_format(what, buffer, buffer_sz);
60 assert_se(r == ret);
61
62 if (r < 0)
63 return;
64
65 assert_se(!memcmp(buffer, expect, r));
66}
67
68static void test_dns_name_to_wire_format(void) {
69 const char out1[] = { 3, 'f', 'o', 'o', 0 };
70 const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
71 const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
72
73 test_dns_name_to_wire_format_one("", NULL, 0, -EINVAL);
74
75 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1), sizeof(out1));
76 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) + 1, sizeof(out1));
77 test_dns_name_to_wire_format_one("foo", out1, sizeof(out1) - 1, -ENOBUFS);
78
79 test_dns_name_to_wire_format_one("hallo.foo.bar", out2, sizeof(out2), sizeof(out2));
80 test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
81
82 test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
83}
84
642900d3
TG
85static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
86 char buffer[buffer_sz];
87 const char *label;
88 int r;
89
90 label = what + strlen(what);
91
92 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
93 assert_se(r == ret1);
94 if (r >= 0)
95 assert_se(streq(buffer, expect1));
96
97 r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz);
98 assert_se(r == ret2);
99 if (r >= 0)
100 assert_se(streq(buffer, expect2));
101}
102
103static void test_dns_label_unescape_suffix(void) {
104 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0);
105 test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOSPC, -ENOSPC);
106 test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0);
107 test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0);
108 test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5);
109 test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL);
110 test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL);
111 test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0);
112 test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0);
113 test_dns_label_unescape_suffix_one("..", "", "", 20, 0, 0);
114 test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL);
115 test_dns_label_unescape_suffix_one("foobar.", "", "foobar", 20, 0, 6);
116 test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0);
117 test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3);
118 test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL);
119 test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL);
120 test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0);
121 test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4);
122 test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0);
123}
124
74b2466e
LP
125static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
126 _cleanup_free_ char *t = NULL;
127 int r;
128
129 r = dns_label_escape(what, l, &t);
0c0cdb06 130 assert_se(r == ret);
74b2466e
LP
131
132 if (r < 0)
133 return;
134
135 assert_se(streq_ptr(expect, t));
136}
137
138static void test_dns_label_escape(void) {
139 test_dns_label_escape_one("", 0, "", 0);
140 test_dns_label_escape_one("hallo", 5, "hallo", 5);
141 test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
142 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
143}
144
145static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
146 _cleanup_free_ char *t = NULL;
147 int r;
148
149 r = dns_name_normalize(what, &t);
150 assert_se(r == ret);
151
152 if (r < 0)
153 return;
154
155 assert_se(streq_ptr(expect, t));
156}
157
158static void test_dns_name_normalize(void) {
159 test_dns_name_normalize_one("", "", 0);
160 test_dns_name_normalize_one("f", "f", 0);
161 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
162 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
163 test_dns_name_normalize_one("\\000", NULL, -EINVAL);
164 test_dns_name_normalize_one("..", NULL, -EINVAL);
165 test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
166 test_dns_name_normalize_one("foobar.", "foobar", 0);
167 test_dns_name_normalize_one(".", "", 0);
168}
169
170static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
171 int r;
172
173 r = dns_name_equal(a, b);
174 assert_se(r == ret);
175
176 r = dns_name_equal(b, a);
177 assert_se(r == ret);
178}
179
180static void test_dns_name_equal(void) {
181 test_dns_name_equal_one("", "", true);
182 test_dns_name_equal_one("x", "x", true);
183 test_dns_name_equal_one("x", "x.", true);
184 test_dns_name_equal_one("abc.def", "abc.def", true);
185 test_dns_name_equal_one("abc.def", "ABC.def", true);
186 test_dns_name_equal_one("abc.def", "CBA.def", false);
187 test_dns_name_equal_one("", "xxx", false);
188 test_dns_name_equal_one("ab", "a", false);
189 test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
190 test_dns_name_equal_one(".", "", true);
191 test_dns_name_equal_one(".", ".", true);
192 test_dns_name_equal_one("..", "..", -EINVAL);
193}
194
ae72b22c
TG
195static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
196 int r;
197
198 r = dns_name_between(a, b, c);
199 assert_se(r == ret);
200
201 r = dns_name_between(c, b, a);
202 if (ret >= 0)
203 assert_se(r == 0);
204 else
205 assert_se(r == ret);
206}
207
208static void test_dns_name_between(void) {
209 /* see https://tools.ietf.org/html/rfc4034#section-6.1
210 Note that we use "\033.z.example" in stead of "\001.z.example" as we
211 consider the latter invalid */
212 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
213 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
214 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
215 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
216 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
217 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
218 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
219 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
220 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
221
222 test_dns_name_between_one("example", "a.example", "example", -EINVAL);
223 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
224 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
225}
226
74b2466e
LP
227static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
228 assert_se(dns_name_endswith(a, b) == ret);
229}
230
231static void test_dns_name_endswith(void) {
232 test_dns_name_endswith_one("", "", true);
233 test_dns_name_endswith_one("", "xxx", false);
234 test_dns_name_endswith_one("xxx", "", true);
235 test_dns_name_endswith_one("x", "x", true);
236 test_dns_name_endswith_one("x", "y", false);
237 test_dns_name_endswith_one("x.y", "y", true);
238 test_dns_name_endswith_one("x.y", "Y", true);
239 test_dns_name_endswith_one("x.y", "x", false);
240 test_dns_name_endswith_one("x.y.z", "Z", true);
241 test_dns_name_endswith_one("x.y.z", "y.Z", true);
242 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
243 test_dns_name_endswith_one("x.y.z", "waldo", false);
244 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
245 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
246 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
247}
248
249static void test_dns_name_root(void) {
250 assert_se(dns_name_root("") == true);
251 assert_se(dns_name_root(".") == true);
252 assert_se(dns_name_root("xxx") == false);
253 assert_se(dns_name_root("xxx.") == false);
254 assert_se(dns_name_root("..") == -EINVAL);
255}
256
257static void test_dns_name_single_label(void) {
258 assert_se(dns_name_single_label("") == false);
259 assert_se(dns_name_single_label(".") == false);
260 assert_se(dns_name_single_label("..") == -EINVAL);
261 assert_se(dns_name_single_label("x") == true);
262 assert_se(dns_name_single_label("x.") == true);
263 assert_se(dns_name_single_label("xx.yy") == false);
264}
265
b914e211
LP
266static void test_dns_name_reverse_one(const char *address, const char *name) {
267 _cleanup_free_ char *p = NULL;
a7f7d1bd 268 union in_addr_union a, b = {};
b914e211
LP
269 int familya, familyb;
270
271 assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
272 assert_se(dns_name_reverse(familya, &a, &p) >= 0);
273 assert_se(streq(p, name));
274 assert_se(dns_name_address(p, &familyb, &b) > 0);
275 assert_se(familya == familyb);
276 assert_se(in_addr_equal(familya, &a, &b));
277}
278
279static void test_dns_name_reverse(void) {
280 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
281 test_dns_name_reverse_one("fe80::47", "7.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa");
9436e8ca
LP
282 test_dns_name_reverse_one("127.0.0.1", "1.0.0.127.in-addr.arpa");
283 test_dns_name_reverse_one("::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa");
b914e211
LP
284}
285
9ca45586
LP
286static void test_dns_name_concat_one(const char *a, const char *b, int r, const char *result) {
287 _cleanup_free_ char *p = NULL;
288
289 assert_se(dns_name_concat(a, b, &p) == r);
290 assert_se(streq_ptr(p, result));
291}
292
293static void test_dns_name_concat(void) {
294 test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
295 test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
296 test_dns_name_concat_one("foo", NULL, 0, "foo");
297 test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
298}
299
300static void test_dns_name_is_valid_one(const char *s, int ret) {
301 assert_se(dns_name_is_valid(s) == ret);
302}
303
304static void test_dns_name_is_valid(void) {
305 test_dns_name_is_valid_one("foo", 1);
306 test_dns_name_is_valid_one("foo.", 1);
307 test_dns_name_is_valid_one("Foo", 1);
308 test_dns_name_is_valid_one("foo.bar", 1);
309 test_dns_name_is_valid_one("foo.bar.baz", 1);
310 test_dns_name_is_valid_one("", 1);
311 test_dns_name_is_valid_one("foo..bar", 0);
312 test_dns_name_is_valid_one(".foo.bar", 0);
313 test_dns_name_is_valid_one("foo.bar.", 1);
314 test_dns_name_is_valid_one("\\zbar", 0);
315 test_dns_name_is_valid_one("รค", 1);
316 test_dns_name_is_valid_one("\n", 0);
317}
318
74b2466e
LP
319int main(int argc, char *argv[]) {
320
321 test_dns_label_unescape();
642900d3 322 test_dns_label_unescape_suffix();
74b2466e
LP
323 test_dns_label_escape();
324 test_dns_name_normalize();
325 test_dns_name_equal();
326 test_dns_name_endswith();
ae72b22c 327 test_dns_name_between();
74b2466e
LP
328 test_dns_name_root();
329 test_dns_name_single_label();
b914e211 330 test_dns_name_reverse();
9ca45586
LP
331 test_dns_name_concat();
332 test_dns_name_is_valid();
54adabf7 333 test_dns_name_to_wire_format();
74b2466e
LP
334
335 return 0;
336}