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