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