1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
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.
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.
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/>.
23 #include "dns-domain.h"
25 static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
26 char buffer[buffer_sz];
29 r = dns_label_unescape(&what, buffer, buffer_sz);
35 assert_se(streq(buffer, expect));
38 static void test_dns_label_unescape(void) {
39 test_dns_label_unescape_one("hallo", "hallo", 6, 5);
40 test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
41 test_dns_label_unescape_one("", "", 10, 0);
42 test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
43 test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
44 test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
45 test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
46 test_dns_label_unescape_one("hallo\\032 ", "hallo ", 20, 7);
47 test_dns_label_unescape_one(".", "", 20, 0);
48 test_dns_label_unescape_one("..", "", 20, -EINVAL);
49 test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
50 test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
53 static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
54 _cleanup_free_ char *t = NULL;
57 r = dns_label_escape(what, l, &t);
63 assert_se(streq_ptr(expect, t));
66 static void test_dns_label_escape(void) {
67 test_dns_label_escape_one("", 0, "", 0);
68 test_dns_label_escape_one("hallo", 5, "hallo", 5);
69 test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
70 test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
73 static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
74 _cleanup_free_ char *t = NULL;
77 r = dns_name_normalize(what, &t);
83 assert_se(streq_ptr(expect, t));
86 static void test_dns_name_normalize(void) {
87 test_dns_name_normalize_one("", "", 0);
88 test_dns_name_normalize_one("f", "f", 0);
89 test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
90 test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
91 test_dns_name_normalize_one("\\000", NULL, -EINVAL);
92 test_dns_name_normalize_one("..", NULL, -EINVAL);
93 test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
94 test_dns_name_normalize_one("foobar.", "foobar", 0);
95 test_dns_name_normalize_one(".", "", 0);
98 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
101 r = dns_name_equal(a, b);
104 r = dns_name_equal(b, a);
108 static void test_dns_name_equal(void) {
109 test_dns_name_equal_one("", "", true);
110 test_dns_name_equal_one("x", "x", true);
111 test_dns_name_equal_one("x", "x.", true);
112 test_dns_name_equal_one("abc.def", "abc.def", true);
113 test_dns_name_equal_one("abc.def", "ABC.def", true);
114 test_dns_name_equal_one("abc.def", "CBA.def", false);
115 test_dns_name_equal_one("", "xxx", false);
116 test_dns_name_equal_one("ab", "a", false);
117 test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
118 test_dns_name_equal_one(".", "", true);
119 test_dns_name_equal_one(".", ".", true);
120 test_dns_name_equal_one("..", "..", -EINVAL);
123 static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) {
126 r = dns_name_between(a, b, c);
129 r = dns_name_between(c, b, a);
136 static void test_dns_name_between(void) {
137 /* see https://tools.ietf.org/html/rfc4034#section-6.1
138 Note that we use "\033.z.example" in stead of "\001.z.example" as we
139 consider the latter invalid */
140 test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true);
141 test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true);
142 test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true);
143 test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true);
144 test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true);
145 test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true);
146 test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true);
147 test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
148 test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
150 test_dns_name_between_one("example", "a.example", "example", -EINVAL);
151 test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
152 test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
155 static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
156 assert_se(dns_name_endswith(a, b) == ret);
159 static void test_dns_name_endswith(void) {
160 test_dns_name_endswith_one("", "", true);
161 test_dns_name_endswith_one("", "xxx", false);
162 test_dns_name_endswith_one("xxx", "", true);
163 test_dns_name_endswith_one("x", "x", true);
164 test_dns_name_endswith_one("x", "y", false);
165 test_dns_name_endswith_one("x.y", "y", true);
166 test_dns_name_endswith_one("x.y", "Y", true);
167 test_dns_name_endswith_one("x.y", "x", false);
168 test_dns_name_endswith_one("x.y.z", "Z", true);
169 test_dns_name_endswith_one("x.y.z", "y.Z", true);
170 test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
171 test_dns_name_endswith_one("x.y.z", "waldo", false);
172 test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
173 test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
174 test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
177 static void test_dns_name_root(void) {
178 assert_se(dns_name_root("") == true);
179 assert_se(dns_name_root(".") == true);
180 assert_se(dns_name_root("xxx") == false);
181 assert_se(dns_name_root("xxx.") == false);
182 assert_se(dns_name_root("..") == -EINVAL);
185 static void test_dns_name_single_label(void) {
186 assert_se(dns_name_single_label("") == false);
187 assert_se(dns_name_single_label(".") == false);
188 assert_se(dns_name_single_label("..") == -EINVAL);
189 assert_se(dns_name_single_label("x") == true);
190 assert_se(dns_name_single_label("x.") == true);
191 assert_se(dns_name_single_label("xx.yy") == false);
194 static void test_dns_name_reverse_one(const char *address, const char *name) {
195 _cleanup_free_ char *p = NULL;
196 union in_addr_union a, b = {};
197 int familya, familyb;
199 assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
200 assert_se(dns_name_reverse(familya, &a, &p) >= 0);
201 assert_se(streq(p, name));
202 assert_se(dns_name_address(p, &familyb, &b) > 0);
203 assert_se(familya == familyb);
204 assert_se(in_addr_equal(familya, &a, &b));
207 static void test_dns_name_reverse(void) {
208 test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
209 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");
212 int main(int argc, char *argv[]) {
214 test_dns_label_unescape();
215 test_dns_label_escape();
216 test_dns_name_normalize();
217 test_dns_name_equal();
218 test_dns_name_endswith();
219 test_dns_name_between();
220 test_dns_name_root();
221 test_dns_name_single_label();
222 test_dns_name_reverse();