1/*
2 * Copyright (C) 2004-2007, 2011  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2003  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: rdata_test.c,v 1.48.814.2 2011/08/28 23:45:47 tbox Exp $ */
19
20#include <config.h>
21
22#include <stdlib.h>
23
24#include <isc/buffer.h>
25#include <isc/commandline.h>
26#include <isc/lex.h>
27#include <isc/mem.h>
28#include <isc/string.h>
29#include <isc/util.h>
30
31#include <dns/rdata.h>
32#include <dns/compress.h>
33#include <dns/rdataclass.h>
34#include <dns/rdatastruct.h>
35#include <dns/rdatatype.h>
36#include <dns/result.h>
37
38isc_mem_t *mctx;
39isc_lex_t *lex;
40
41isc_lexspecials_t specials;
42
43static void
44viastruct(dns_rdata_t *rdata, isc_mem_t *mctx,
45	  dns_rdata_t *rdata2, isc_buffer_t *b)
46{
47	isc_result_t result;
48	void *sp = NULL;
49	isc_boolean_t need_free = ISC_FALSE;
50	dns_rdatatype_t rdt;
51	dns_rdataclass_t rdc;
52
53	UNUSED(rdata2);	/* XXXMPA remove when fromstruct is ready. */
54	UNUSED(b);
55
56	switch (rdata->type) {
57	case dns_rdatatype_a6: {
58		dns_rdata_in_a6_t in_a6;
59		result = dns_rdata_tostruct(rdata, sp = &in_a6, NULL);
60		break;
61	}
62	case dns_rdatatype_a: {
63		switch (rdata->rdclass) {
64		case dns_rdataclass_hs: {
65			dns_rdata_hs_a_t hs_a;
66			result = dns_rdata_tostruct(rdata, sp = &hs_a, NULL);
67			break;
68		}
69		case dns_rdataclass_in: {
70			dns_rdata_in_a_t in_a;
71			result = dns_rdata_tostruct(rdata, sp = &in_a, NULL);
72			break;
73		}
74		default:
75			result = ISC_R_NOTIMPLEMENTED;
76			break;
77		}
78		break;
79	}
80	case dns_rdatatype_aaaa: {
81		dns_rdata_in_aaaa_t in_aaaa;
82		result = dns_rdata_tostruct(rdata, sp = &in_aaaa, NULL);
83		break;
84	}
85	case dns_rdatatype_afsdb: {
86		dns_rdata_afsdb_t afsdb;
87		result = dns_rdata_tostruct(rdata, sp = &afsdb, NULL);
88		break;
89	}
90	case dns_rdatatype_any: {
91		result = ISC_R_NOTIMPLEMENTED;
92		break;
93	}
94	case dns_rdatatype_apl: {
95		switch (rdata->rdclass) {
96		case dns_rdataclass_in: {
97			dns_rdata_in_apl_t in_apl;
98			result = dns_rdata_tostruct(rdata, sp = &in_apl, NULL);
99			break;
100		}
101		default:
102			result = ISC_R_NOTIMPLEMENTED;
103			break;
104		}
105		break;
106	}
107	case dns_rdatatype_cert: {
108		dns_rdata_cert_t cert;
109		result = dns_rdata_tostruct(rdata, sp = &cert, NULL);
110		break;
111	}
112	case dns_rdatatype_cname: {
113		dns_rdata_cname_t cname;
114		result = dns_rdata_tostruct(rdata, sp = &cname, NULL);
115		break;
116	}
117	case dns_rdatatype_dname: {
118		dns_rdata_dname_t dname;
119		result = dns_rdata_tostruct(rdata, sp = &dname, NULL);
120		break;
121	}
122	case dns_rdatatype_gpos: {
123		dns_rdata_gpos_t gpos;
124		result = dns_rdata_tostruct(rdata, sp = &gpos, NULL);
125		break;
126	}
127	case dns_rdatatype_hinfo: {
128		dns_rdata_hinfo_t hinfo;
129		result = dns_rdata_tostruct(rdata, sp = &hinfo, NULL);
130		break;
131	}
132	case dns_rdatatype_isdn: {
133		dns_rdata_isdn_t isdn;
134		result = dns_rdata_tostruct(rdata, sp = &isdn, NULL);
135		break;
136	}
137	case dns_rdatatype_key: {
138		dns_rdata_key_t key;
139		result = dns_rdata_tostruct(rdata, sp = &key, NULL);
140		break;
141	}
142	case dns_rdatatype_kx: {
143		dns_rdata_in_kx_t in_kx;
144		result = dns_rdata_tostruct(rdata, sp = &in_kx, NULL);
145		break;
146	}
147	case dns_rdatatype_loc: {
148		dns_rdata_loc_t loc;
149		result = dns_rdata_tostruct(rdata, sp = &loc, NULL);
150		break;
151	}
152	case dns_rdatatype_mb: {
153		dns_rdata_mb_t mb;
154		result = dns_rdata_tostruct(rdata, sp = &mb, NULL);
155		break;
156	}
157	case dns_rdatatype_md: {
158		dns_rdata_md_t md;
159		result = dns_rdata_tostruct(rdata, sp = &md, NULL);
160		break;
161	}
162	case dns_rdatatype_mf: {
163		dns_rdata_mf_t mf;
164		result = dns_rdata_tostruct(rdata, sp = &mf, NULL);
165		break;
166	}
167	case dns_rdatatype_mg: {
168		dns_rdata_mg_t mg;
169		result = dns_rdata_tostruct(rdata, sp = &mg, NULL);
170		break;
171	}
172	case dns_rdatatype_minfo: {
173		dns_rdata_minfo_t minfo;
174		result = dns_rdata_tostruct(rdata, sp = &minfo, NULL);
175		break;
176	}
177	case dns_rdatatype_mr: {
178		dns_rdata_mr_t mr;
179		result = dns_rdata_tostruct(rdata, sp = &mr, NULL);
180		break;
181	}
182	case dns_rdatatype_mx: {
183		dns_rdata_mx_t mx;
184		result = dns_rdata_tostruct(rdata, sp = &mx, NULL);
185		break;
186	}
187	case dns_rdatatype_naptr: {
188		dns_rdata_in_naptr_t in_naptr;
189		result = dns_rdata_tostruct(rdata, sp = &in_naptr, NULL);
190		break;
191	}
192	case dns_rdatatype_ns: {
193		dns_rdata_ns_t ns;
194		result = dns_rdata_tostruct(rdata, sp = &ns, NULL);
195		break;
196	}
197	case dns_rdatatype_nsap: {
198		dns_rdata_in_nsap_t in_nsap;
199		result = dns_rdata_tostruct(rdata, sp = &in_nsap, NULL);
200		break;
201	}
202	case dns_rdatatype_nsap_ptr: {
203		dns_rdata_in_nsap_ptr_t in_nsap_ptr;
204		result = dns_rdata_tostruct(rdata, sp = &in_nsap_ptr, NULL);
205		break;
206	}
207	case dns_rdatatype_null: {
208		dns_rdata_null_t null;
209		result = dns_rdata_tostruct(rdata, sp = &null, NULL);
210		break;
211	}
212	case dns_rdatatype_nxt: {
213		dns_rdata_nxt_t nxt;
214		result = dns_rdata_tostruct(rdata, sp = &nxt, NULL);
215		break;
216	}
217	case dns_rdatatype_opt: {
218		dns_rdata_opt_t opt;
219		result = dns_rdata_tostruct(rdata, sp = &opt, NULL);
220		break;
221	}
222	case dns_rdatatype_ptr: {
223		dns_rdata_ptr_t ptr;
224		result = dns_rdata_tostruct(rdata, sp = &ptr, NULL);
225		break;
226	}
227	case dns_rdatatype_px: {
228		dns_rdata_in_px_t in_px;
229		result = dns_rdata_tostruct(rdata, sp = &in_px, NULL);
230		break;
231	}
232	case dns_rdatatype_rp: {
233		dns_rdata_rp_t rp;
234		result = dns_rdata_tostruct(rdata, sp = &rp, NULL);
235		break;
236	}
237	case dns_rdatatype_rt: {
238		dns_rdata_rt_t rt;
239		result = dns_rdata_tostruct(rdata, sp = &rt, NULL);
240		break;
241	}
242	case dns_rdatatype_sig: {
243		dns_rdata_sig_t sig;
244		result = dns_rdata_tostruct(rdata, sp = &sig, NULL);
245		break;
246	}
247	case dns_rdatatype_soa: {
248		dns_rdata_soa_t soa;
249		result = dns_rdata_tostruct(rdata, sp = &soa, NULL);
250		break;
251	}
252	case dns_rdatatype_srv: {
253		dns_rdata_in_srv_t in_srv;
254		result = dns_rdata_tostruct(rdata, sp = &in_srv, NULL);
255		break;
256	}
257	case dns_rdatatype_tkey: {
258		dns_rdata_tkey_t tkey;
259		result = dns_rdata_tostruct(rdata, sp = &tkey, NULL);
260		break;
261	}
262	case dns_rdatatype_tsig: {
263		dns_rdata_any_tsig_t tsig;
264		result = dns_rdata_tostruct(rdata, sp = &tsig, NULL);
265		break;
266	}
267	case dns_rdatatype_txt: {
268		dns_rdata_txt_t txt;
269		result = dns_rdata_tostruct(rdata, sp = &txt, NULL);
270		break;
271	}
272	case dns_rdatatype_spf: {
273		dns_rdata_spf_t spf;
274		result = dns_rdata_tostruct(rdata, sp = &spf, NULL);
275		break;
276	}
277	case dns_rdatatype_unspec: {
278		dns_rdata_unspec_t unspec;
279		result = dns_rdata_tostruct(rdata, sp = &unspec, NULL);
280		break;
281	}
282	case dns_rdatatype_wks: {
283		dns_rdata_in_wks_t in_wks;
284		result = dns_rdata_tostruct(rdata, sp = &in_wks, NULL);
285		break;
286	}
287	case dns_rdatatype_x25: {
288		dns_rdata_x25_t x25;
289		result = dns_rdata_tostruct(rdata, sp = &x25, NULL);
290		break;
291	}
292	case dns_rdatatype_nsec: {
293		dns_rdata_nsec_t nsec;
294		result = dns_rdata_tostruct(rdata, sp = &nsec, NULL);
295		break;
296	}
297	case dns_rdatatype_rrsig: {
298		dns_rdata_rrsig_t rrsig;
299		result = dns_rdata_tostruct(rdata, sp = &rrsig, NULL);
300		break;
301	}
302	case dns_rdatatype_dnskey: {
303		dns_rdata_dnskey_t dnskey;
304		result = dns_rdata_tostruct(rdata, sp = &dnskey, NULL);
305		break;
306	}
307	default:
308		result = ISC_R_NOTIMPLEMENTED;
309		break;
310	}
311	if (result != ISC_R_SUCCESS)
312		fprintf(stdout, "viastruct: tostruct %d %d return %s\n",
313			rdata->type, rdata->rdclass,
314			dns_result_totext(result));
315	else
316		dns_rdata_freestruct(sp);
317
318	switch (rdata->type) {
319	case dns_rdatatype_a6: {
320		dns_rdata_in_a6_t in_a6;
321		result = dns_rdata_tostruct(rdata, sp = &in_a6, mctx);
322		break;
323	}
324	case dns_rdatatype_a: {
325		switch (rdata->rdclass) {
326		case dns_rdataclass_hs: {
327			dns_rdata_hs_a_t hs_a;
328			result = dns_rdata_tostruct(rdata, sp = &hs_a, mctx);
329			break;
330		}
331		case dns_rdataclass_in: {
332			dns_rdata_in_a_t in_a;
333			result = dns_rdata_tostruct(rdata, sp = &in_a, mctx);
334			break;
335		}
336		default:
337			result = ISC_R_NOTIMPLEMENTED;
338			break;
339		}
340		break;
341	}
342	case dns_rdatatype_aaaa: {
343		dns_rdata_in_aaaa_t in_aaaa;
344		result = dns_rdata_tostruct(rdata, sp = &in_aaaa, mctx);
345		break;
346	}
347	case dns_rdatatype_afsdb: {
348		dns_rdata_afsdb_t afsdb;
349		result = dns_rdata_tostruct(rdata, sp = &afsdb, mctx);
350		break;
351	}
352	case dns_rdatatype_any: {
353		result = ISC_R_NOTIMPLEMENTED;
354		break;
355	}
356	case dns_rdatatype_apl: {
357		switch (rdata->rdclass) {
358		case dns_rdataclass_in: {
359			dns_rdata_in_apl_t in_apl;
360			result = dns_rdata_tostruct(rdata, sp = &in_apl, mctx);
361			break;
362		}
363		default:
364			result = ISC_R_NOTIMPLEMENTED;
365			break;
366		}
367		break;
368	}
369	case dns_rdatatype_cert: {
370		dns_rdata_cert_t cert;
371		result = dns_rdata_tostruct(rdata, sp = &cert, mctx);
372		break;
373	}
374	case dns_rdatatype_cname: {
375		dns_rdata_cname_t cname;
376		result = dns_rdata_tostruct(rdata, sp = &cname, mctx);
377		break;
378	}
379	case dns_rdatatype_dname: {
380		dns_rdata_dname_t dname;
381		result = dns_rdata_tostruct(rdata, sp = &dname, mctx);
382		break;
383	}
384	case dns_rdatatype_gpos: {
385		dns_rdata_gpos_t gpos;
386		result = dns_rdata_tostruct(rdata, sp = &gpos, mctx);
387		break;
388	}
389	case dns_rdatatype_hinfo: {
390		dns_rdata_hinfo_t hinfo;
391		result = dns_rdata_tostruct(rdata, sp = &hinfo, mctx);
392		break;
393	}
394	case dns_rdatatype_isdn: {
395		dns_rdata_isdn_t isdn;
396		result = dns_rdata_tostruct(rdata, sp = &isdn, mctx);
397		break;
398	}
399	case dns_rdatatype_key: {
400		dns_rdata_key_t key;
401		result = dns_rdata_tostruct(rdata, sp = &key, mctx);
402		break;
403	}
404	case dns_rdatatype_kx: {
405		dns_rdata_in_kx_t in_kx;
406		result = dns_rdata_tostruct(rdata, sp = &in_kx, mctx);
407		break;
408	}
409	case dns_rdatatype_loc: {
410		dns_rdata_loc_t loc;
411		result = dns_rdata_tostruct(rdata, sp = &loc, mctx);
412		break;
413	}
414	case dns_rdatatype_mb: {
415		dns_rdata_mb_t mb;
416		result = dns_rdata_tostruct(rdata, sp = &mb, mctx);
417		break;
418	}
419	case dns_rdatatype_md: {
420		dns_rdata_md_t md;
421		result = dns_rdata_tostruct(rdata, sp = &md, mctx);
422		break;
423	}
424	case dns_rdatatype_mf: {
425		dns_rdata_mf_t mf;
426		result = dns_rdata_tostruct(rdata, sp = &mf, mctx);
427		break;
428	}
429	case dns_rdatatype_mg: {
430		dns_rdata_mg_t mg;
431		result = dns_rdata_tostruct(rdata, sp = &mg, mctx);
432		break;
433	}
434	case dns_rdatatype_minfo: {
435		dns_rdata_minfo_t minfo;
436		result = dns_rdata_tostruct(rdata, sp = &minfo, mctx);
437		break;
438	}
439	case dns_rdatatype_mr: {
440		dns_rdata_mr_t mr;
441		result = dns_rdata_tostruct(rdata, sp = &mr, mctx);
442		break;
443	}
444	case dns_rdatatype_mx: {
445		dns_rdata_mx_t mx;
446		result = dns_rdata_tostruct(rdata, sp = &mx, mctx);
447		break;
448	}
449	case dns_rdatatype_naptr: {
450		dns_rdata_in_naptr_t in_naptr;
451		result = dns_rdata_tostruct(rdata, sp = &in_naptr, mctx);
452		break;
453	}
454	case dns_rdatatype_ns: {
455		dns_rdata_ns_t ns;
456		result = dns_rdata_tostruct(rdata, sp = &ns, mctx);
457		break;
458	}
459	case dns_rdatatype_nsap: {
460		dns_rdata_in_nsap_t in_nsap;
461		result = dns_rdata_tostruct(rdata, sp = &in_nsap, mctx);
462		break;
463	}
464	case dns_rdatatype_nsap_ptr: {
465		dns_rdata_in_nsap_ptr_t in_nsap_ptr;
466		result = dns_rdata_tostruct(rdata, sp = &in_nsap_ptr, mctx);
467		break;
468	}
469	case dns_rdatatype_null: {
470		dns_rdata_null_t null;
471		result = dns_rdata_tostruct(rdata, sp = &null, mctx);
472		break;
473	}
474	case dns_rdatatype_nxt: {
475		dns_rdata_nxt_t nxt;
476		result = dns_rdata_tostruct(rdata, sp = &nxt, mctx);
477		break;
478	}
479	case dns_rdatatype_opt: {
480		dns_rdata_opt_t opt;
481		result = dns_rdata_tostruct(rdata, sp = &opt, mctx);
482		break;
483	}
484	case dns_rdatatype_ptr: {
485		dns_rdata_ptr_t ptr;
486		result = dns_rdata_tostruct(rdata, sp = &ptr, mctx);
487		break;
488	}
489	case dns_rdatatype_px: {
490		dns_rdata_in_px_t in_px;
491		result = dns_rdata_tostruct(rdata, sp = &in_px, mctx);
492		break;
493	}
494	case dns_rdatatype_rp: {
495		dns_rdata_rp_t rp;
496		result = dns_rdata_tostruct(rdata, sp = &rp, mctx);
497		break;
498	}
499	case dns_rdatatype_rt: {
500		dns_rdata_rt_t rt;
501		result = dns_rdata_tostruct(rdata, sp = &rt, mctx);
502		break;
503	}
504	case dns_rdatatype_sig: {
505		dns_rdata_sig_t sig;
506		result = dns_rdata_tostruct(rdata, sp = &sig, mctx);
507		break;
508	}
509	case dns_rdatatype_soa: {
510		dns_rdata_soa_t soa;
511		result = dns_rdata_tostruct(rdata, sp = &soa, mctx);
512		break;
513	}
514	case dns_rdatatype_srv: {
515		dns_rdata_in_srv_t in_srv;
516		result = dns_rdata_tostruct(rdata, sp = &in_srv, mctx);
517		break;
518	}
519	case dns_rdatatype_tkey: {
520		dns_rdata_tkey_t tkey;
521		result = dns_rdata_tostruct(rdata, sp = &tkey, mctx);
522		break;
523	}
524	case dns_rdatatype_tsig: {
525		dns_rdata_any_tsig_t tsig;
526		result = dns_rdata_tostruct(rdata, sp = &tsig, mctx);
527		break;
528	}
529	case dns_rdatatype_txt: {
530		dns_rdata_txt_t txt;
531		result = dns_rdata_tostruct(rdata, sp = &txt, mctx);
532		break;
533	}
534	case dns_rdatatype_spf: {
535		dns_rdata_spf_t spf;
536		result = dns_rdata_tostruct(rdata, sp = &spf, mctx);
537		break;
538	}
539	case dns_rdatatype_unspec: {
540		dns_rdata_unspec_t unspec;
541		result = dns_rdata_tostruct(rdata, sp = &unspec, mctx);
542		break;
543	}
544	case dns_rdatatype_wks: {
545		dns_rdata_in_wks_t in_wks;
546		result = dns_rdata_tostruct(rdata, sp = &in_wks, mctx);
547		break;
548	}
549	case dns_rdatatype_x25: {
550		dns_rdata_x25_t x25;
551		result = dns_rdata_tostruct(rdata, sp = &x25, mctx);
552		break;
553	}
554	case dns_rdatatype_nsec: {
555		dns_rdata_nsec_t nsec;
556		result = dns_rdata_tostruct(rdata, sp = &nsec, mctx);
557		break;
558	}
559	case dns_rdatatype_rrsig: {
560		dns_rdata_rrsig_t rrsig;
561		result = dns_rdata_tostruct(rdata, sp = &rrsig, mctx);
562		break;
563	}
564	case dns_rdatatype_dnskey: {
565		dns_rdata_dnskey_t dnskey;
566		result = dns_rdata_tostruct(rdata, sp = &dnskey, mctx);
567		break;
568	}
569	default:
570		result = ISC_R_NOTIMPLEMENTED;
571		break;
572	}
573	if (result != ISC_R_SUCCESS)
574		fprintf(stdout, "viastruct: tostruct %d %d return %s\n",
575			rdata->type, rdata->rdclass,
576			dns_result_totext(result));
577	else {
578		need_free = ISC_TRUE;
579
580		rdc = rdata->rdclass;
581		rdt = rdata->type;
582		result = dns_rdata_fromstruct(rdata2, rdc, rdt, sp, b);
583		if (result != ISC_R_SUCCESS)
584			fprintf(stdout,
585				"viastruct: fromstruct %d %d return %s\n",
586				rdata->type, rdata->rdclass,
587				dns_result_totext(result));
588		else if (rdata->length != rdata2->length ||
589			 memcmp(rdata->data, rdata2->data, rdata->length) != 0)
590		{
591			isc_uint32_t i;
592			isc_uint32_t l;
593
594			fprintf(stdout, "viastruct: memcmp failed\n");
595
596			fprintf(stdout, "%d %d\n",
597				rdata->length, rdata2->length);
598			l = rdata->length;
599			if (rdata2->length < l)
600				l = rdata2->length;
601			for (i = 0; i < l; i++)
602				fprintf(stdout, "%02x %02x\n",
603					rdata->data[i], rdata2->data[i]);
604		}
605	}
606#if 0
607	switch (rdata->type) {
608	case dns_rdatatype_a6: {
609		dns_rdata_in_a6_t in_a6;
610		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_a6, b);
611		break;
612	}
613	case dns_rdatatype_a: {
614		switch (rdata->rdclass) {
615		case dns_rdataclass_hs: {
616			dns_rdata_hs_a_t hs_a;
617			result = dns_rdata_fromstruct(rdata2, rdc, rdt,
618						      &hs_a, b);
619			break;
620		}
621		case dns_rdataclass_in: {
622			dns_rdata_in_a_t in_a;
623			result = dns_rdata_fromstruct(rdata2, rdc, rdt,
624						      &in_a, b);
625			break;
626		}
627		default:
628			result = ISC_R_NOTIMPLEMENTED;
629			break;
630		}
631		break;
632	}
633	case dns_rdatatype_aaaa: {
634		dns_rdata_in_aaaa_t in_aaaa;
635		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_aaaa, b);
636		break;
637	}
638	case dns_rdatatype_afsdb: {
639		dns_rdata_afsdb_t afsdb;
640		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &afsdb, b);
641		break;
642	}
643	case dns_rdatatype_any: {
644		result = ISC_R_NOTIMPLEMENTED;
645		break;
646	}
647	case dns_rdatatype_apl: {
648		switch (rdata->rdclass) {
649		case dns_rdataclass_in: {
650			dns_rdata_in_apl_t in_apl;
651			result = dns_rdata_fromstruct(rdata, rdc, rdt, &in_apl,							      b);
652			break;
653		}
654		default:
655			result = ISC_R_NOTIMPLEMENTED;
656			break;
657		}
658		break;
659	}
660	case dns_rdatatype_cert: {
661		dns_rdata_cert_t cert;
662		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &cert, b);
663		break;
664	}
665	case dns_rdatatype_cname: {
666		dns_rdata_cname_t cname;
667		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &cname, b);
668		break;
669	}
670	case dns_rdatatype_dname: {
671		dns_rdata_dname_t dname;
672		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &dname, b);
673		break;
674	}
675	case dns_rdatatype_gpos: {
676		dns_rdata_gpos_t gpos;
677		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &gpos, b);
678		break;
679	}
680	case dns_rdatatype_hinfo: {
681		dns_rdata_hinfo_t hinfo;
682		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &hinfo, b);
683		break;
684	}
685	case dns_rdatatype_isdn: {
686		dns_rdata_isdn_t isdn;
687		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &isdn, b);
688		break;
689	}
690	case dns_rdatatype_key: {
691		dns_rdata_key_t key;
692		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &key, b);
693		break;
694	}
695	case dns_rdatatype_kx: {
696		dns_rdata_in_kx_t in_kx;
697		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_kx, b);
698		break;
699	}
700	case dns_rdatatype_loc: {
701		dns_rdata_loc_t loc;
702		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &loc, b);
703		break;
704	}
705	case dns_rdatatype_mb: {
706		dns_rdata_mb_t mb;
707		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &mb, b);
708		break;
709	}
710	case dns_rdatatype_md: {
711		dns_rdata_md_t md;
712		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &md, b);
713		break;
714	}
715	case dns_rdatatype_mf: {
716		dns_rdata_mf_t mf;
717		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &mf, b);
718		break;
719	}
720	case dns_rdatatype_mg: {
721		dns_rdata_mg_t mg;
722		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &mg, b);
723		break;
724	}
725	case dns_rdatatype_minfo: {
726		dns_rdata_minfo_t minfo;
727		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &minfo, b);
728		break;
729	}
730	case dns_rdatatype_mr: {
731		dns_rdata_mr_t mr;
732		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &mr, b);
733		break;
734	}
735	case dns_rdatatype_mx: {
736		dns_rdata_mx_t mx;
737		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &mx, b);
738		break;
739	}
740	case dns_rdatatype_naptr: {
741		dns_rdata_in_naptr_t in_naptr;
742		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_naptr, b);
743		break;
744	}
745	case dns_rdatatype_ns: {
746		dns_rdata_ns_t ns;
747		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &ns, b);
748		break;
749	}
750	case dns_rdatatype_nsap: {
751		dns_rdata_in_nsap_t in_nsap;
752		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_nsap, b);
753		break;
754	}
755	case dns_rdatatype_nsap_ptr: {
756		dns_rdata_in_nsap_ptr_t in_nsap_ptr;
757		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_nsap_ptr,
758					      b);
759		break;
760	}
761	case dns_rdatatype_null: {
762		dns_rdata_null_t null;
763		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &null, b);
764		break;
765	}
766	case dns_rdatatype_nxt: {
767		dns_rdata_nxt_t nxt;
768		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &nxt, b);
769		break;
770	}
771	case dns_rdatatype_opt: {
772		dns_rdata_opt_t opt;
773		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &opt, b);
774		break;
775	}
776	case dns_rdatatype_ptr: {
777		dns_rdata_ptr_t ptr;
778		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &ptr, b);
779		break;
780	}
781	case dns_rdatatype_px: {
782		dns_rdata_in_px_t in_px;
783		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_px, b);
784		break;
785	}
786	case dns_rdatatype_rp: {
787		dns_rdata_rp_t rp;
788		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &rp, b);
789		break;
790	}
791	case dns_rdatatype_rt: {
792		dns_rdata_rt_t rt;
793		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &rt, b);
794		break;
795	}
796	case dns_rdatatype_sig: {
797		dns_rdata_sig_t sig;
798		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &sig, b);
799		break;
800	}
801	case dns_rdatatype_soa: {
802		dns_rdata_soa_t soa;
803		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &soa, b);
804		break;
805	}
806	case dns_rdatatype_srv: {
807		dns_rdata_in_srv_t in_srv;
808		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_srv, b);
809		break;
810	}
811	case dns_rdatatype_tkey: {
812		dns_rdata_tkey_t tkey;
813		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &tkey, b);
814		break;
815	}
816	case dns_rdatatype_tsig: {
817		dns_rdata_any_tsig_t tsig;
818		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &tsig, b);
819		break;
820	}
821	case dns_rdatatype_txt: {
822		dns_rdata_txt_t txt;
823		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &txt, b);
824		break;
825	}
826	case dns_rdatatype_spf: {
827		dns_rdata_spf_t spf;
828		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &spf, b);
829		break;
830	}
831	case dns_rdatatype_unspec: {
832		dns_rdata_unspec_t unspec;
833		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &unspec, b);
834		break;
835	}
836	case dns_rdatatype_wks: {
837		dns_rdata_in_wks_t in_wks;
838		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_wks, b);
839		break;
840	}
841	case dns_rdatatype_x25: {
842		dns_rdata_x25_t x25;
843		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &x25, b);
844		break;
845	}
846	case dns_rdatatype_nsec: {
847		dns_rdata_nsec_t nsec;
848		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &nsec, b);
849		break;
850	}
851	case dns_rdatatype_rrsig: {
852		dns_rdata_rrsig_t rrsig;
853		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &rrsig, b);
854		break;
855	}
856	case dns_rdatatype_dnskey: {
857		dns_rdata_dnskey_t dnskey;
858		result = dns_rdata_fromstruct(rdata2, rdc, rdt, &dnskey, b);
859		break;
860	}
861	default:
862		result = ISC_R_NOTIMPLEMENTED;
863		break;
864	}
865#endif
866	if (need_free)
867		dns_rdata_freestruct(sp);
868}
869
870int
871main(int argc, char *argv[]) {
872	isc_token_t token;
873	isc_result_t result;
874	int quiet = 0;
875	int c;
876	int stats = 0;
877	unsigned int options = 0;
878	dns_rdatatype_t type;
879	dns_rdataclass_t class;
880	dns_rdatatype_t lasttype = 0;
881	char outbuf[16*1024];
882	char inbuf[16*1024];
883	char wirebuf[16*1024];
884	char viabuf[16*1024];
885	isc_buffer_t dbuf;
886	isc_buffer_t tbuf;
887	isc_buffer_t wbuf;
888	dns_rdata_t rdata = DNS_RDATA_INIT;
889	dns_rdata_t last = DNS_RDATA_INIT;
890	int need_eol = 0;
891	int wire = 0;
892	dns_compress_t cctx;
893	dns_decompress_t dctx;
894	int trunc = 0;
895	int add = 0;
896	int len;
897	int zero = 0;
898	int debug = 0;
899	isc_region_t region;
900	int first = 1;
901	int raw = 0;
902	int tostruct = 0;
903
904	while ((c = isc_commandline_parse(argc, argv, "dqswtarzS")) != -1) {
905		switch (c) {
906		case 'd':
907			debug = 1;
908			quiet = 0;
909			break;
910		case 'q':
911			quiet = 1;
912			debug = 0;
913			break;
914		case 's':
915			stats = 1;
916			break;
917		case 'w':
918			wire = 1;
919			break;
920		case 't':
921			trunc = 1;
922			break;
923		case 'a':
924			add = 1;
925			break;
926		case 'z':
927			zero = 1;
928			break;
929		case 'r':
930			raw++;
931			break;
932		case 'S':
933			tostruct++;
934			break;
935		}
936	}
937
938	memset(&dctx, 0, sizeof(dctx));
939	dctx.allowed = DNS_COMPRESS_ALL;
940
941	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
942	RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS);
943
944	/*
945	 * Set up to lex DNS master file.
946	 */
947
948	specials['('] = 1;
949	specials[')'] = 1;
950	specials['"'] = 1;
951	isc_lex_setspecials(lex, specials);
952	options = ISC_LEXOPT_EOL;
953	isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
954
955	RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS);
956
957	dns_rdata_init(&last);
958	while ((result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER,
959					  &token)) == ISC_R_SUCCESS) {
960		if (debug) fprintf(stdout, "token.type = %d\n", token.type);
961		if (need_eol) {
962			if (token.type == isc_tokentype_eol)
963				need_eol = 0;
964			continue;
965		}
966		if (token.type == isc_tokentype_eof)
967			break;
968
969		/*
970		 * Get type.
971		 */
972		if (token.type == isc_tokentype_number) {
973			type = token.value.as_ulong;
974			isc_buffer_init(&tbuf, outbuf, sizeof(outbuf));
975			result = dns_rdatatype_totext(type, &tbuf);
976			if (result != ISC_R_SUCCESS) {
977				fprintf(stdout,
978					"dns_rdatatype_totext "
979					"returned %s(%d)\n",
980					dns_result_totext(result), result);
981				fflush(stdout);
982				need_eol = 1;
983				continue;
984			}
985			fprintf(stdout, "type = %.*s(%d)\n",
986				(int)tbuf.used, (char*)tbuf.base, type);
987		} else if (token.type == isc_tokentype_string) {
988			result = dns_rdatatype_fromtext(&type,
989					&token.value.as_textregion);
990			if (result != ISC_R_SUCCESS) {
991				fprintf(stdout,
992					"dns_rdatatype_fromtext "
993					"returned %s(%d)\n",
994					dns_result_totext(result), result);
995				fflush(stdout);
996				need_eol = 1;
997				continue;
998			}
999			fprintf(stdout, "type = %.*s(%d)\n",
1000				(int)token.value.as_textregion.length,
1001				token.value.as_textregion.base, type);
1002		} else
1003			continue;
1004
1005		result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER,
1006					  &token);
1007		if (result != ISC_R_SUCCESS)
1008			break;
1009		if (token.type == isc_tokentype_eol)
1010			continue;
1011		if (token.type == isc_tokentype_eof)
1012			break;
1013		if (token.type == isc_tokentype_number) {
1014			class = token.value.as_ulong;
1015			isc_buffer_init(&tbuf, outbuf, sizeof(outbuf));
1016			result = dns_rdatatype_totext(class, &tbuf);
1017			if (result != ISC_R_SUCCESS) {
1018				fprintf(stdout, "dns_rdatatype_totext "
1019					"returned %s(%d)\n",
1020					dns_result_totext(result), result);
1021				fflush(stdout);
1022				need_eol = 1;
1023				continue;
1024			}
1025			fprintf(stdout, "class = %.*s(%d)\n",
1026				(int)tbuf.used, (char*)tbuf.base, class);
1027		} else if (token.type == isc_tokentype_string) {
1028			result = dns_rdataclass_fromtext(&class,
1029					&token.value.as_textregion);
1030			if (result != ISC_R_SUCCESS) {
1031				fprintf(stdout, "dns_rdataclass_fromtext "
1032					"returned %s(%d)\n",
1033					dns_result_totext(result), result);
1034				fflush(stdout);
1035				need_eol = 1;
1036				continue;
1037			}
1038			fprintf(stdout, "class = %.*s(%d)\n",
1039				(int)token.value.as_textregion.length,
1040				token.value.as_textregion.base, class);
1041		} else
1042			continue;
1043
1044		fflush(stdout);
1045		dns_rdata_init(&rdata);
1046		isc_buffer_init(&dbuf, inbuf, sizeof(inbuf));
1047		result = dns_rdata_fromtext(&rdata, class, type, lex,
1048					    NULL, 0, mctx, &dbuf,
1049					    NULL);
1050		if (result != ISC_R_SUCCESS) {
1051			fprintf(stdout,
1052				"dns_rdata_fromtext returned %s(%d)\n",
1053				dns_result_totext(result), result);
1054			fflush(stdout);
1055			continue;
1056		}
1057		if (raw) {
1058			unsigned int i;
1059			for (i = 0; i < rdata.length; /* */ ) {
1060				fprintf(stdout, "%02x", rdata.data[i]);
1061				if ((++i % 20) == 0)
1062					fputs("\n", stdout);
1063				else
1064					if (i == rdata.length)
1065						fputs("\n", stdout);
1066					else
1067						fputs(" ", stdout);
1068			}
1069		}
1070
1071		/*
1072		 * Convert to wire and back?
1073		 */
1074		if (wire) {
1075			result = dns_compress_init(&cctx, -1, mctx);
1076			if (result != ISC_R_SUCCESS) {
1077				fprintf(stdout,
1078					"dns_compress_init returned %s(%d)\n",
1079					dns_result_totext(result), result);
1080				continue;
1081			}
1082			isc_buffer_init(&wbuf, wirebuf, sizeof(wirebuf));
1083			result = dns_rdata_towire(&rdata, &cctx, &wbuf);
1084			dns_compress_invalidate(&cctx);
1085			if (result != ISC_R_SUCCESS) {
1086				fprintf(stdout,
1087					"dns_rdata_towire returned %s(%d)\n",
1088					dns_result_totext(result), result);
1089				continue;
1090			}
1091			len = wbuf.used - wbuf.current;
1092			if (raw > 2) {
1093				unsigned int i;
1094				fputs("\n", stdout);
1095				for (i = 0; i < (unsigned int)len; /* */ ) {
1096					fprintf(stdout, "%02x",
1097				((unsigned char*)wbuf.base)[i + wbuf.current]);
1098					if ((++i % 20) == 0)
1099						fputs("\n", stdout);
1100					else
1101						if (i == wbuf.used)
1102							fputs("\n", stdout);
1103						else
1104							fputs(" ", stdout);
1105				}
1106			}
1107			if (zero)
1108				len = 0;
1109			if (trunc)
1110				len = (len * 3) / 4;
1111			if (add) {
1112				isc_buffer_add(&wbuf, len / 4 + 1);
1113				len += len / 4 + 1;
1114			}
1115
1116			isc_buffer_setactive(&wbuf, len);
1117			dns_rdata_init(&rdata);
1118			isc_buffer_init(&dbuf, inbuf, sizeof(inbuf));
1119			dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
1120			result = dns_rdata_fromwire(&rdata, class, type, &wbuf,
1121						    &dctx, 0, &dbuf);
1122			dns_decompress_invalidate(&dctx);
1123			if (result != ISC_R_SUCCESS) {
1124			fprintf(stdout,
1125					"dns_rdata_fromwire returned %s(%d)\n",
1126					dns_result_totext(result), result);
1127				fflush(stdout);
1128				continue;
1129			}
1130		}
1131		if (raw > 1) {
1132			unsigned int i;
1133			fputs("\n", stdout);
1134			for (i = 0; i < rdata.length; /* */ ) {
1135				fprintf(stdout, "%02x", rdata.data[i]);
1136				if ((++i % 20) == 0)
1137					fputs("\n", stdout);
1138				else
1139					if (i == rdata.length)
1140						fputs("\n", stdout);
1141					else
1142						fputs(" ", stdout);
1143			}
1144		}
1145		if (tostruct) {
1146			isc_mem_t *mctx2 = NULL;
1147			dns_rdata_t rdata2 = DNS_RDATA_INIT;
1148			isc_buffer_t vbuf;
1149
1150			RUNTIME_CHECK(isc_mem_create(0, 0, &mctx2)
1151				      == ISC_R_SUCCESS);
1152
1153			isc_buffer_init(&vbuf, viabuf, sizeof(viabuf));
1154			dns_rdata_init(&rdata2);
1155			viastruct(&rdata, mctx2, &rdata2, &vbuf);
1156			if (!quiet && stats)
1157				isc_mem_stats(mctx2, stdout);
1158			isc_mem_destroy(&mctx2);
1159		}
1160
1161		isc_buffer_init(&tbuf, outbuf, sizeof(outbuf));
1162		result = dns_rdata_totext(&rdata, NULL, &tbuf);
1163		if (result != ISC_R_SUCCESS)
1164			fprintf(stdout, "dns_rdata_totext returned %s(%d)\n",
1165				dns_result_totext(result), result);
1166		else
1167			fprintf(stdout, "\"%.*s\"\n",
1168				(int)tbuf.used, (char*)tbuf.base);
1169		fflush(stdout);
1170		if (lasttype == type) {
1171			fprintf(stdout, "dns_rdata_compare = %d\n",
1172				dns_rdata_compare(&rdata, &last));
1173
1174		}
1175		if (!first) {
1176			free(last.data);
1177		}
1178		dns_rdata_init(&last);
1179		region.base = malloc(region.length = rdata.length);
1180		if (region.base) {
1181			memcpy(region.base, rdata.data, rdata.length);
1182			dns_rdata_fromregion(&last, class, type, &region);
1183			lasttype = type;
1184			first = 0;
1185		} else
1186			first = 1;
1187
1188	}
1189	if (result != ISC_R_EOF)
1190		printf("Result: %s\n", isc_result_totext(result));
1191
1192	isc_lex_close(lex);
1193	isc_lex_destroy(&lex);
1194	if (!quiet && stats)
1195		isc_mem_stats(mctx, stdout);
1196	isc_mem_destroy(&mctx);
1197
1198	return (0);
1199}
1200