1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 #include <stdbool.h>
13 #include <stdlib.h>
14
15 #include <isc/commandline.h>
16 #include <isc/print.h>
17 #include <isc/string.h>
18 #include <isc/util.h>
19
20 #include <dns/fixedname.h>
21 #include <dns/result.h>
22
23 static void
print_wirename(isc_region_t * name)24 print_wirename(isc_region_t *name) {
25 unsigned char *ccurr, *cend;
26
27 if (name->length == 0) {
28 printf("<empty wire name>\n");
29 return;
30 }
31 ccurr = name->base;
32 cend = ccurr + name->length;
33 while (ccurr != cend) {
34 printf("%02x ", *ccurr++);
35 }
36 printf("\n");
37 }
38
39 static void
print_name(dns_name_t * name)40 print_name(dns_name_t *name) {
41 isc_result_t result;
42 isc_buffer_t source;
43 isc_region_t r;
44 char s[1000];
45
46 isc_buffer_init(&source, s, sizeof(s));
47 if (dns_name_countlabels(name) > 0) {
48 result = dns_name_totext(name, false, &source);
49 } else {
50 result = ISC_R_SUCCESS;
51 }
52 if (result == ISC_R_SUCCESS) {
53 isc_buffer_usedregion(&source, &r);
54 if (r.length > 0) {
55 printf("%.*s\n", (int)r.length, r.base);
56 } else {
57 printf("<empty text name>\n");
58 }
59 } else {
60 printf("error: %s\n", dns_result_totext(result));
61 }
62 }
63
64 int
main(int argc,char * argv[])65 main(int argc, char *argv[]) {
66 char s[1000];
67 isc_result_t result;
68 dns_fixedname_t wname, wname2, oname, compname, downname;
69 isc_buffer_t source;
70 isc_region_t r;
71 dns_name_t *name, *comp, *down;
72 const dns_name_t *origin;
73 unsigned int downcase = 0;
74 size_t len;
75 bool quiet = false;
76 bool concatenate = false;
77 bool got_name = false;
78 bool check_absolute = false;
79 bool check_wildcard = false;
80 bool test_downcase = false;
81 bool inplace = false;
82 bool want_split = false;
83 unsigned int labels, split_label = 0;
84 dns_fixedname_t fprefix, fsuffix;
85 dns_name_t *prefix, *suffix;
86 int ch;
87
88 while ((ch = isc_commandline_parse(argc, argv, "acdiqs:w")) != -1) {
89 switch (ch) {
90 case 'a':
91 check_absolute = true;
92 break;
93 case 'c':
94 concatenate = true;
95 break;
96 case 'd':
97 test_downcase = true;
98 break;
99 case 'i':
100 inplace = true;
101 break;
102 case 'q':
103 quiet = true;
104 break;
105 case 's':
106 want_split = true;
107 split_label = atoi(isc_commandline_argument);
108 break;
109 case 'w':
110 check_wildcard = true;
111 break;
112 }
113 }
114
115 argc -= isc_commandline_index;
116 argv += isc_commandline_index;
117
118 if (argc > 0) {
119 if (strcasecmp("none", argv[0]) == 0) {
120 origin = NULL;
121 } else {
122 len = strlen(argv[0]);
123 isc_buffer_init(&source, argv[0], len);
124 isc_buffer_add(&source, len);
125 dns_fixedname_init(&oname);
126 result = dns_name_fromtext(dns_fixedname_name(&oname),
127 &source, dns_rootname, 0,
128 NULL);
129 if (result != 0) {
130 fprintf(stderr,
131 "dns_name_fromtext() failed: %s\n",
132 dns_result_totext(result));
133 exit(1);
134 }
135 origin = dns_fixedname_name(&oname);
136 }
137 } else if (concatenate) {
138 origin = NULL;
139 } else {
140 origin = dns_rootname;
141 }
142
143 if (argc >= 1) {
144 if (strcasecmp("none", argv[1]) == 0) {
145 comp = NULL;
146 } else {
147 len = strlen(argv[1]);
148 isc_buffer_init(&source, argv[1], len);
149 isc_buffer_add(&source, len);
150 comp = dns_fixedname_initname(&compname);
151 result = dns_name_fromtext(comp, &source, origin, 0,
152 NULL);
153 if (result != 0) {
154 fprintf(stderr,
155 "dns_name_fromtext() failed: %s\n",
156 dns_result_totext(result));
157 exit(1);
158 }
159 }
160 } else {
161 comp = NULL;
162 }
163
164 name = dns_fixedname_initname(&wname);
165 dns_fixedname_init(&wname2);
166 while (fgets(s, sizeof(s), stdin) != NULL) {
167 len = strlen(s);
168 if (len > 0U && s[len - 1] == '\n') {
169 s[len - 1] = '\0';
170 len--;
171 }
172 isc_buffer_init(&source, s, len);
173 isc_buffer_add(&source, len);
174
175 if (len > 0U) {
176 result = dns_name_fromtext(name, &source, origin,
177 downcase, NULL);
178 } else {
179 if (name == dns_fixedname_name(&wname)) {
180 dns_fixedname_init(&wname);
181 } else {
182 dns_fixedname_init(&wname2);
183 }
184 result = ISC_R_SUCCESS;
185 }
186
187 if (result != ISC_R_SUCCESS) {
188 printf("%s\n", dns_result_totext(result));
189 if (name == dns_fixedname_name(&wname)) {
190 dns_fixedname_init(&wname);
191 } else {
192 dns_fixedname_init(&wname2);
193 }
194 continue;
195 }
196
197 if (check_absolute && dns_name_countlabels(name) > 0) {
198 if (dns_name_isabsolute(name)) {
199 printf("absolute\n");
200 } else {
201 printf("relative\n");
202 }
203 }
204 if (check_wildcard && dns_name_countlabels(name) > 0) {
205 if (dns_name_iswildcard(name)) {
206 printf("wildcard\n");
207 } else {
208 printf("not wildcard\n");
209 }
210 }
211 dns_name_toregion(name, &r);
212 if (!quiet) {
213 print_wirename(&r);
214 printf("%u labels, %u bytes.\n",
215 dns_name_countlabels(name), r.length);
216 }
217
218 if (concatenate) {
219 if (got_name) {
220 printf("Concatenating.\n");
221 result = dns_name_concatenate(
222 dns_fixedname_name(&wname),
223 dns_fixedname_name(&wname2),
224 dns_fixedname_name(&wname2), NULL);
225 name = dns_fixedname_name(&wname2);
226 if (result == ISC_R_SUCCESS) {
227 if (check_absolute &&
228 dns_name_countlabels(name) > 0) {
229 if (dns_name_isabsolute(name)) {
230 printf("absolute\n");
231 } else {
232 printf("relative\n");
233 }
234 }
235 if (check_wildcard &&
236 dns_name_countlabels(name) > 0) {
237 if (dns_name_iswildcard(name)) {
238 printf("wildcard\n");
239 } else {
240 printf("not "
241 "wildcard\n");
242 }
243 }
244 dns_name_toregion(name, &r);
245 if (!quiet) {
246 print_wirename(&r);
247 printf("%u labels, "
248 "%u bytes.\n",
249 dns_name_countlabels(
250 name),
251 r.length);
252 }
253 } else {
254 printf("%s\n",
255 dns_result_totext(result));
256 }
257 got_name = false;
258 } else {
259 got_name = true;
260 }
261 }
262 isc_buffer_init(&source, s, sizeof(s));
263 if (dns_name_countlabels(name) > 0) {
264 result = dns_name_totext(name, false, &source);
265 } else {
266 result = ISC_R_SUCCESS;
267 }
268 if (result == ISC_R_SUCCESS) {
269 isc_buffer_usedregion(&source, &r);
270 if (r.length > 0) {
271 printf("%.*s\n", (int)r.length, r.base);
272 } else {
273 printf("<empty text name>\n");
274 }
275 if (!quiet) {
276 printf("%u bytes.\n", source.used);
277 }
278 } else {
279 printf("%s\n", dns_result_totext(result));
280 }
281
282 if (test_downcase) {
283 if (inplace) {
284 down = name;
285 } else {
286 down = dns_fixedname_initname(&downname);
287 }
288 result = dns_name_downcase(name, down, NULL);
289 INSIST(result == ISC_R_SUCCESS);
290 if (!quiet) {
291 dns_name_toregion(down, &r);
292 print_wirename(&r);
293 printf("%u labels, %u bytes.\n",
294 dns_name_countlabels(down), r.length);
295 }
296 isc_buffer_init(&source, s, sizeof(s));
297 print_name(down);
298 }
299
300 if (comp != NULL && dns_name_countlabels(name) > 0) {
301 int order;
302 unsigned int nlabels;
303 dns_namereln_t namereln;
304
305 namereln = dns_name_fullcompare(name, comp, &order,
306 &nlabels);
307 if (!quiet) {
308 if (order < 0) {
309 printf("<");
310 } else if (order > 0) {
311 printf(">");
312 } else {
313 printf("=");
314 }
315 switch (namereln) {
316 case dns_namereln_contains:
317 printf(", contains");
318 break;
319 case dns_namereln_subdomain:
320 printf(", subdomain");
321 break;
322 case dns_namereln_commonancestor:
323 printf(", common ancestor");
324 break;
325 default:
326 break;
327 }
328 if (namereln != dns_namereln_none &&
329 namereln != dns_namereln_equal) {
330 printf(", nlabels = %u", nlabels);
331 }
332 printf("\n");
333 }
334 printf("dns_name_equal() returns %s\n",
335 dns_name_equal(name, comp) ? "TRUE" : "FALSE");
336 }
337
338 labels = dns_name_countlabels(name);
339 if (want_split && split_label < labels) {
340 prefix = dns_fixedname_initname(&fprefix);
341 suffix = dns_fixedname_initname(&fsuffix);
342 printf("splitting at label %u: ", split_label);
343 dns_name_split(name, split_label, prefix, suffix);
344 printf("\n prefix = ");
345 print_name(prefix);
346 printf(" suffix = ");
347 print_name(suffix);
348 }
349
350 if (concatenate) {
351 if (got_name) {
352 name = dns_fixedname_name(&wname2);
353 } else {
354 name = dns_fixedname_name(&wname);
355 }
356 }
357 }
358
359 return (0);
360 }
361