etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / bin / tools / named-rrchecker.c
blob1e7d96deeab878fd6ef89b659d2ef331ff219bf9
1 /* $NetBSD: named-rrchecker.c,v 1.1.1.3 2014/12/10 03:34:31 christos Exp $ */
3 /*
4 * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 #include <config.h>
21 #include <stdlib.h>
23 #include <isc/buffer.h>
24 #include <isc/commandline.h>
25 #include <isc/lex.h>
26 #include <isc/mem.h>
27 #include <isc/string.h>
28 #include <isc/util.h>
30 #include <dns/fixedname.h>
31 #include <dns/name.h>
32 #include <dns/rdata.h>
33 #include <dns/rdataclass.h>
34 #include <dns/rdatatype.h>
35 #include <dns/result.h>
37 static isc_mem_t *mctx;
38 static isc_lex_t *lex;
40 static isc_lexspecials_t specials;
42 static void
43 usage(void) {
44 fprintf(stderr, "usage: named-rrchecker [-o origin] [-hpCPT]\n");
45 fprintf(stderr, "\t-h: print this help message\n");
46 fprintf(stderr, "\t-o origin: set origin to be used when interpeting the record\n");
47 fprintf(stderr, "\t-p: print the record in cannonical format\n");
48 fprintf(stderr, "\t-C: list the supported class names\n");
49 fprintf(stderr, "\t-T: list the supported standard type names\n");
50 fprintf(stderr, "\t-P: list the supported private type names\n");
53 int
54 main(int argc, char *argv[]) {
55 isc_token_t token;
56 isc_result_t result;
57 int c;
58 unsigned int options = 0;
59 dns_rdatatype_t rdtype;
60 dns_rdataclass_t rdclass;
61 char text[256*1024];
62 char data[64*1024];
63 isc_buffer_t tbuf;
64 isc_buffer_t dbuf;
65 dns_rdata_t rdata = DNS_RDATA_INIT;
66 isc_boolean_t doexit = ISC_FALSE;
67 isc_boolean_t once = ISC_FALSE;
68 isc_boolean_t print = ISC_FALSE;
69 isc_boolean_t unknown = ISC_FALSE;
70 unsigned int t;
71 char *origin = NULL;
72 dns_fixedname_t fixed;
73 dns_name_t *name = NULL;
75 while ((c = isc_commandline_parse(argc, argv, "ho:puCPT")) != -1) {
76 switch (c) {
77 case '?':
78 case 'h':
79 if (isc_commandline_option != '?' &&
80 isc_commandline_option != 'h')
81 fprintf(stderr, "%s: invalid argument -%c\n",
82 argv[0], isc_commandline_option);
83 usage();
84 exit(1);
86 case 'o':
87 origin = isc_commandline_argument;
88 break;
90 case 'p':
91 print = ISC_TRUE;
92 break;
94 case 'u':
95 unknown = ISC_TRUE;
96 break;
98 case 'C':
99 for (t = 1; t <= 0xfeffu; t++) {
100 if (dns_rdataclass_ismeta(t))
101 continue;
102 dns_rdataclass_format(t, text, sizeof(text));
103 if (strncmp(text, "CLASS", 4) != 0)
104 fprintf(stdout, "%s\n", text);
106 exit(0);
108 case 'P':
109 for (t = 0xff00; t <= 0xfffeu; t++) {
110 if (dns_rdatatype_ismeta(t))
111 continue;
112 dns_rdatatype_format(t, text, sizeof(text));
113 if (strncmp(text, "TYPE", 4) != 0)
114 fprintf(stdout, "%s\n", text);
116 doexit = ISC_TRUE;
117 break;
119 case 'T':
120 for (t = 1; t <= 0xfeffu; t++) {
121 if (dns_rdatatype_ismeta(t))
122 continue;
123 dns_rdatatype_format(t, text, sizeof(text));
124 if (strncmp(text, "TYPE", 4) != 0)
125 fprintf(stdout, "%s\n", text);
127 doexit = ISC_TRUE;
128 break;
131 if (doexit)
132 exit(0);
134 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
135 RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS);
138 * Set up to lex DNS master file.
141 specials['('] = 1;
142 specials[')'] = 1;
143 specials['"'] = 1;
144 isc_lex_setspecials(lex, specials);
145 options = ISC_LEXOPT_EOL;
146 isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
148 RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS);
150 if (origin != NULL) {
151 dns_fixedname_init(&fixed);
152 name = dns_fixedname_name(&fixed);
153 result = dns_name_fromstring(name, origin, 0, NULL);
154 if (result != ISC_R_SUCCESS) {
155 fprintf(stderr, "dns_name_fromstring: %s\n",
156 dns_result_totext(result));
157 fflush(stderr);
158 exit(1);
162 while ((result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER,
163 &token)) == ISC_R_SUCCESS) {
164 if (token.type == isc_tokentype_eof)
165 break;
166 if (token.type == isc_tokentype_eol)
167 continue;
168 if (once) {
169 fprintf(stderr, "extra data\n");
170 exit(1);
173 * Get class.
175 if (token.type == isc_tokentype_number) {
176 rdclass = (dns_rdataclass_t) token.value.as_ulong;
177 if (token.value.as_ulong > 0xffffu) {
178 fprintf(stderr, "class value too big %lu\n",
179 token.value.as_ulong);
180 fflush(stderr);
181 exit(1);
183 if (dns_rdataclass_ismeta(rdclass)) {
184 fprintf(stderr, "class %lu is a meta value\n",
185 token.value.as_ulong);
186 fflush(stderr);
187 exit(1);
189 } else if (token.type == isc_tokentype_string) {
190 result = dns_rdataclass_fromtext(&rdclass,
191 &token.value.as_textregion);
192 if (result != ISC_R_SUCCESS) {
193 fprintf(stderr, "dns_rdataclass_fromtext: %s\n",
194 dns_result_totext(result));
195 fflush(stderr);
196 exit(1);
198 if (dns_rdataclass_ismeta(rdclass)) {
199 fprintf(stderr,
200 "class %.*s(%d) is a meta value\n",
201 (int)token.value.as_textregion.length,
202 token.value.as_textregion.base, rdclass);
203 fflush(stderr);
204 exit(1);
206 } else {
207 fprintf(stderr, "unexpected token %u\n", token.type);
208 exit(1);
211 result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER,
212 &token);
213 if (result != ISC_R_SUCCESS)
214 break;
215 if (token.type == isc_tokentype_eol)
216 continue;
217 if (token.type == isc_tokentype_eof)
218 break;
221 * Get type.
223 if (token.type == isc_tokentype_number) {
224 rdtype = (dns_rdatatype_t) token.value.as_ulong;
225 if (token.value.as_ulong > 0xffffu) {
226 fprintf(stderr, "type value too big %lu\n",
227 token.value.as_ulong);
228 exit(1);
230 if (dns_rdatatype_ismeta(rdtype)) {
231 fprintf(stderr, "type %lu is a meta value\n",
232 token.value.as_ulong);
233 fflush(stderr);
234 exit(1);
236 } else if (token.type == isc_tokentype_string) {
237 result = dns_rdatatype_fromtext(&rdtype,
238 &token.value.as_textregion);
239 if (result != ISC_R_SUCCESS) {
240 fprintf(stdout, "dns_rdatatype_fromtext: %s\n",
241 dns_result_totext(result));
242 fflush(stdout);
243 exit(1);
245 if (dns_rdatatype_ismeta(rdtype)) {
246 fprintf(stderr,
247 "type %.*s(%d) is a meta value\n",
248 (int)token.value.as_textregion.length,
249 token.value.as_textregion.base, rdtype);
250 fflush(stderr);
251 exit(1);
253 } else {
254 fprintf(stderr, "unexpected token %u\n", token.type);
255 exit(1);
258 isc_buffer_init(&dbuf, data, sizeof(data));
259 result = dns_rdata_fromtext(&rdata, rdclass, rdtype, lex,
260 name, 0, mctx, &dbuf, NULL);
261 if (result != ISC_R_SUCCESS) {
262 fprintf(stderr, "dns_rdata_fromtext: %s\n",
263 dns_result_totext(result));
264 fflush(stderr);
265 exit(1);
267 once = ISC_TRUE;
269 if (result != ISC_R_EOF) {
270 fprintf(stderr, "eof not found\n");
271 exit(1);
273 if (!once) {
274 fprintf(stderr, "no records found\n");
275 exit(1);
278 if (print) {
279 isc_buffer_init(&tbuf, text, sizeof(text));
280 result = dns_rdataclass_totext(rdclass, &tbuf);
281 if (result != ISC_R_SUCCESS) {
282 fprintf(stderr, "dns_rdataclass_totext: %s\n",
283 dns_result_totext(result));
284 fflush(stderr);
285 exit(1);
287 isc_buffer_putstr(&tbuf, "\t");
288 result = dns_rdatatype_totext(rdtype, &tbuf);
289 if (result != ISC_R_SUCCESS) {
290 fprintf(stderr, "dns_rdatatype_totext: %s\n",
291 dns_result_totext(result));
292 fflush(stderr);
293 exit(1);
295 isc_buffer_putstr(&tbuf, "\t");
296 result = dns_rdata_totext(&rdata, NULL, &tbuf);
297 if (result != ISC_R_SUCCESS)
298 fprintf(stderr, "dns_rdata_totext: %s\n",
299 dns_result_totext(result));
300 else
301 fprintf(stdout, "%.*s\n", (int)tbuf.used,
302 (char*)tbuf.base);
303 fflush(stdout);
306 if (unknown) {
307 fprintf(stdout, "CLASS%u\tTYPE%u\t\\# %u", rdclass, rdtype,
308 rdata.length);
309 if (rdata.length != 0) {
310 unsigned int i;
311 fprintf(stdout, " ");
312 for (i = 0; i < rdata.length; i++)
313 fprintf(stdout, "%02x", rdata.data[i]);
315 fprintf(stdout, "\n");
318 isc_lex_close(lex);
319 isc_lex_destroy(&lex);
320 isc_mem_destroy(&mctx);
321 return (0);