1%{
2/*
3 * zyparser.y -- yacc grammar for (DNS) zone files
4 *
5 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
6 *
7 * See LICENSE for the license.
8 *
9 */
10
11#include "config.h"
12
13#include <stdarg.h>
14#include <stdio.h>
15#include <string.h>
16
17#include "dname.h"
18#include "namedb.h"
19#include "zonec.h"
20
21/* these need to be global, otherwise they cannot be used inside yacc */
22zparser_type *parser;
23
24#ifdef __cplusplus
25extern "C"
26#endif /* __cplusplus */
27int yywrap(void);
28
29/* this hold the nxt bits */
30static uint8_t nxtbits[16];
31static int dlv_warn = 1;
32
33/* 256 windows of 256 bits (32 bytes) */
34/* still need to reset the bastard somewhere */
35static uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
36
37/* hold the highest rcode seen in a NSEC rdata , BUG #106 */
38uint16_t nsec_highest_rcode;
39
40void yyerror(const char *message);
41
42#ifdef NSEC3
43/* parse nsec3 parameters and add the (first) rdata elements */
44static void
45nsec3_add_params(const char* hash_algo_str, const char* flag_str,
46	const char* iter_str, const char* salt_str, int salt_len);
47#endif /* NSEC3 */
48
49%}
50%union {
51	domain_type	 *domain;
52	const dname_type *dname;
53	struct lex_data	  data;
54	uint32_t	  ttl;
55	uint16_t	  klass;
56	uint16_t	  type;
57	uint16_t	 *unknown;
58}
59
60/*
61 * Tokens to represent the known RR types of DNS.
62 */
63%token <type> T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG
64%token <type> T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO
65%token <type> T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX
66%token <type> T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK
67%token <type> T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR
68%token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY
69%token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI
70%token <type> T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY
71%token <type> T_OPENPGPKEY T_CSYNC T_ZONEMD T_AVC T_SMIMEA T_SVCB T_HTTPS
72
73/* other tokens */
74%token	       DOLLAR_TTL DOLLAR_ORIGIN NL SP
75%token <data>  QSTR STR PREV BITLAB
76%token <ttl>   T_TTL
77%token <klass> T_RRCLASS
78
79/* unknown RRs */
80%token	       URR
81%token <type>  T_UTYPE
82
83%type <type>	type_and_rdata
84%type <domain>	owner dname abs_dname
85%type <dname>	rel_dname label
86%type <data>	wire_dname wire_abs_dname wire_rel_dname wire_label
87%type <data>	str concatenated_str_seq str_sp_seq str_dot_seq
88%type <data>	unquoted_dotted_str dotted_str svcparam svcparams
89%type <data>	nxt_seq nsec_more
90%type <unknown> rdata_unknown
91
92%%
93lines:	/* empty file */
94    |	lines line
95    ;
96
97line:	NL
98    |	sp NL
99    |	PREV NL		{}    /* Lines containing only whitespace.  */
100    |	ttl_directive
101	{
102	    region_free_all(parser->rr_region);
103	    parser->current_rr.type = 0;
104	    parser->current_rr.rdata_count = 0;
105	    parser->current_rr.rdatas = parser->temporary_rdatas;
106	    parser->error_occurred = 0;
107    }
108    |	origin_directive
109	{
110	    region_free_all(parser->rr_region);
111	    parser->current_rr.type = 0;
112	    parser->current_rr.rdata_count = 0;
113	    parser->current_rr.rdatas = parser->temporary_rdatas;
114	    parser->error_occurred = 0;
115    }
116    |	rr
117    {	/* rr should be fully parsed */
118	    if (!parser->error_occurred) {
119			    parser->current_rr.rdatas
120				    =(rdata_atom_type *)region_alloc_array_init(
121					    parser->region,
122					    parser->current_rr.rdatas,
123					    parser->current_rr.rdata_count,
124					    sizeof(rdata_atom_type));
125
126			    process_rr();
127	    }
128
129	    region_free_all(parser->rr_region);
130
131	    parser->current_rr.type = 0;
132	    parser->current_rr.rdata_count = 0;
133	    parser->current_rr.rdatas = parser->temporary_rdatas;
134	    parser->error_occurred = 0;
135    }
136    |	error NL
137    ;
138
139/* needed to cope with ( and ) in arbitrary places */
140sp:	SP
141    |	sp SP
142    ;
143
144str:	STR | QSTR;
145
146trail:	NL
147    |	sp NL
148    ;
149
150ttl_directive:	DOLLAR_TTL sp str trail
151    {
152	    parser->default_ttl = zparser_ttl2int($3.str, &(parser->error_occurred));
153	    if (parser->error_occurred == 1) {
154		    parser->default_ttl = DEFAULT_TTL;
155			parser->error_occurred = 0;
156	    }
157    }
158    ;
159
160origin_directive:	DOLLAR_ORIGIN sp abs_dname trail
161    {
162	    /* if previous origin is unused, remove it, do not leak it */
163	    if(parser->origin != error_domain && parser->origin != $3) {
164		/* protect $3 from deletion, because deldomain walks up */
165		$3->usage ++;
166	    	domain_table_deldomain(parser->db, parser->origin);
167		$3->usage --;
168	    }
169	    parser->origin = $3;
170    }
171    |	DOLLAR_ORIGIN sp rel_dname trail
172    {
173	    zc_error_prev_line("$ORIGIN directive requires absolute domain name");
174    }
175    ;
176
177rr:	owner classttl type_and_rdata
178    {
179	    parser->current_rr.owner = $1;
180	    parser->current_rr.type = $3;
181    }
182    ;
183
184owner:	dname sp
185    {
186	    parser->prev_dname = $1;
187	    $$ = $1;
188    }
189    |	PREV
190    {
191	    $$ = parser->prev_dname;
192    }
193    ;
194
195classttl:	/* empty - fill in the default, def. ttl and IN class */
196    {
197	    parser->current_rr.ttl = parser->default_ttl;
198	    parser->current_rr.klass = parser->default_class;
199    }
200    |	T_RRCLASS sp		/* no ttl */
201    {
202	    parser->current_rr.ttl = parser->default_ttl;
203	    parser->current_rr.klass = $1;
204    }
205    |	T_TTL sp		/* no class */
206    {
207	    parser->current_rr.ttl = $1;
208	    parser->current_rr.klass = parser->default_class;
209    }
210    |	T_TTL sp T_RRCLASS sp	/* the lot */
211    {
212	    parser->current_rr.ttl = $1;
213	    parser->current_rr.klass = $3;
214    }
215    |	T_RRCLASS sp T_TTL sp	/* the lot - reversed */
216    {
217	    parser->current_rr.ttl = $3;
218	    parser->current_rr.klass = $1;
219    }
220    ;
221
222dname:	abs_dname
223    |	rel_dname
224    {
225	    if ($1 == error_dname) {
226		    $$ = error_domain;
227	    } else if(parser->origin == error_domain) {
228		    zc_error("cannot concatenate origin to domain name, because origin failed to parse");
229		    $$ = error_domain;
230	    } else if ($1->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) {
231		    zc_error("domain name exceeds %d character limit", MAXDOMAINLEN);
232		    $$ = error_domain;
233	    } else {
234		    $$ = domain_table_insert(
235			    parser->db->domains,
236			    dname_concatenate(
237				    parser->rr_region,
238				    $1,
239				    domain_dname(parser->origin)));
240	    }
241    }
242    ;
243
244abs_dname:	'.'
245    {
246	    $$ = parser->db->domains->root;
247    }
248    |	'@'
249    {
250	    $$ = parser->origin;
251    }
252    |	rel_dname '.'
253    {
254	    if ($1 != error_dname) {
255		    $$ = domain_table_insert(parser->db->domains, $1);
256	    } else {
257		    $$ = error_domain;
258	    }
259    }
260    ;
261
262label:	str
263    {
264	    if ($1.len > MAXLABELLEN) {
265		    zc_error("label exceeds %d character limit", MAXLABELLEN);
266		    $$ = error_dname;
267	    } else if ($1.len <= 0) {
268		    zc_error("zero label length");
269		    $$ = error_dname;
270	    } else {
271		    $$ = dname_make_from_label(parser->rr_region,
272					       (uint8_t *) $1.str,
273					       $1.len);
274	    }
275    }
276    |	BITLAB
277    {
278	    zc_error("bitlabels are now deprecated. RFC2673 is obsoleted.");
279	    $$ = error_dname;
280    }
281    ;
282
283rel_dname:	label
284    |	rel_dname '.' label
285    {
286	    if ($1 == error_dname || $3 == error_dname) {
287		    $$ = error_dname;
288	    } else if ($1->name_size + $3->name_size - 1 > MAXDOMAINLEN) {
289		    zc_error("domain name exceeds %d character limit",
290			     MAXDOMAINLEN);
291		    $$ = error_dname;
292	    } else {
293		    $$ = dname_concatenate(parser->rr_region, $1, $3);
294	    }
295    }
296    ;
297
298/*
299 * Some dnames in rdata are handled as opaque blobs
300 */
301
302wire_dname:	wire_abs_dname
303    |	wire_rel_dname
304    {
305	    /* terminate in root label and copy the origin in there */
306	    if(parser->origin && domain_dname(parser->origin)) {
307		    $$.len = $1.len + domain_dname(parser->origin)->name_size;
308		    if ($$.len > MAXDOMAINLEN)
309			    zc_error("domain name exceeds %d character limit",
310				     MAXDOMAINLEN);
311		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
312		    memmove($$.str, $1.str, $1.len);
313		    memmove($$.str + $1.len, dname_name(domain_dname(parser->origin)),
314			domain_dname(parser->origin)->name_size);
315	    } else {
316		    $$.len = $1.len + 1;
317		    if ($$.len > MAXDOMAINLEN)
318			    zc_error("domain name exceeds %d character limit",
319				     MAXDOMAINLEN);
320		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
321		    memmove($$.str, $1.str, $1.len);
322		    $$.str[ $1.len ] = 0;
323	    }
324    }
325    ;
326
327wire_abs_dname:	'.'
328    {
329	    char *result = (char *) region_alloc(parser->rr_region, 1);
330	    result[0] = 0;
331	    $$.str = result;
332	    $$.len = 1;
333    }
334    |	'@'
335    {
336	    if(parser->origin && domain_dname(parser->origin)) {
337		    $$.len = domain_dname(parser->origin)->name_size;
338		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
339		    memmove($$.str, dname_name(domain_dname(parser->origin)), $$.len);
340	    } else {
341		    $$.len = 1;
342		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
343		    $$.str[0] = 0;
344	    }
345    }
346    |	wire_rel_dname '.'
347    {
348	    $$.len = $1.len + 1;
349	    if ($$.len > MAXDOMAINLEN)
350		    zc_error("domain name exceeds %d character limit",
351			     MAXDOMAINLEN);
352	    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
353	    memcpy($$.str, $1.str, $1.len);
354	    $$.str[$1.len] = 0;
355    }
356    ;
357
358wire_label:	str
359    {
360	    char *result = (char *) region_alloc(parser->rr_region,
361						 $1.len + 1);
362
363	    if ($1.len > MAXLABELLEN)
364		    zc_error("label exceeds %d character limit", MAXLABELLEN);
365
366	    /* make label anyway */
367	    result[0] = $1.len;
368	    memmove(result+1, $1.str, $1.len);
369
370	    $$.str = result;
371	    $$.len = $1.len + 1;
372    }
373    ;
374
375wire_rel_dname:	wire_label
376    |	wire_rel_dname '.' wire_label
377    {
378	    $$.len = $1.len + $3.len;
379	    if ($$.len > MAXDOMAINLEN)
380		    zc_error("domain name exceeds %d character limit",
381			     MAXDOMAINLEN);
382	    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
383	    memmove($$.str, $1.str, $1.len);
384	    memmove($$.str + $1.len, $3.str, $3.len);
385    }
386    ;
387
388str_seq:	unquoted_dotted_str
389    {
390	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
391    }
392    |	QSTR
393    {
394	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
395    }
396    |	QSTR unquoted_dotted_str
397    {
398	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
399	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
400    }
401    |	str_seq QSTR
402    {
403	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
404    }
405    |	str_seq QSTR unquoted_dotted_str
406    {
407	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
408	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
409    }
410    |	str_seq sp unquoted_dotted_str
411    {
412	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
413    }
414    |	str_seq sp QSTR
415    {
416	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
417    }
418    |	str_seq sp QSTR unquoted_dotted_str
419    {
420	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
421	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $4.str, $4.len), 0);
422    }
423    ;
424
425/*
426 * Generate a single string from multiple STR tokens, separated by
427 * spaces or dots.
428 */
429concatenated_str_seq:	str
430    |	'.'
431    {
432	    $$.len = 1;
433	    $$.str = region_strdup(parser->rr_region, ".");
434    }
435    |	concatenated_str_seq sp str
436    {
437	    $$.len = $1.len + $3.len + 1;
438	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
439	    memcpy($$.str, $1.str, $1.len);
440	    memcpy($$.str + $1.len, " ", 1);
441	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
442	    $$.str[$$.len] = '\0';
443    }
444    |	concatenated_str_seq '.' str
445    {
446	    $$.len = $1.len + $3.len + 1;
447	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
448	    memcpy($$.str, $1.str, $1.len);
449	    memcpy($$.str + $1.len, ".", 1);
450	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
451	    $$.str[$$.len] = '\0';
452    }
453    ;
454
455/* used to convert a nxt list of types */
456nxt_seq:	str
457    {
458	    uint16_t type = rrtype_from_string($1.str);
459	    if (type != 0 && type < 128) {
460		    set_bit(nxtbits, type);
461	    } else {
462		    zc_error("bad type %d in NXT record", (int) type);
463	    }
464    }
465    |	nxt_seq sp str
466    {
467	    uint16_t type = rrtype_from_string($3.str);
468	    if (type != 0 && type < 128) {
469		    set_bit(nxtbits, type);
470	    } else {
471		    zc_error("bad type %d in NXT record", (int) type);
472	    }
473    }
474    ;
475
476nsec_more:	SP nsec_more
477    {
478    }
479    |	NL
480    {
481    }
482    |	str nsec_seq
483    {
484	    uint16_t type = rrtype_from_string($1.str);
485	    if (type != 0) {
486                    if (type > nsec_highest_rcode) {
487                            nsec_highest_rcode = type;
488                    }
489		    set_bitnsec(nsecbits, type);
490	    } else {
491		    zc_error("bad type %d in NSEC record", (int) type);
492	    }
493    }
494    ;
495
496nsec_seq:	NL
497	|	SP nsec_more
498	;
499
500/*
501 * Sequence of STR tokens separated by spaces.	The spaces are not
502 * preserved during concatenation.
503 */
504str_sp_seq:	str
505    |	str_sp_seq sp str
506    {
507	    char *result = (char *) region_alloc(parser->rr_region,
508						 $1.len + $3.len + 1);
509	    memcpy(result, $1.str, $1.len);
510	    memcpy(result + $1.len, $3.str, $3.len);
511	    $$.str = result;
512	    $$.len = $1.len + $3.len;
513	    $$.str[$$.len] = '\0';
514    }
515    ;
516
517/*
518 * Sequence of STR tokens separated by dots.  The dots are not
519 * preserved during concatenation.
520 */
521str_dot_seq:	str
522    |	str_dot_seq '.' str
523    {
524	    char *result = (char *) region_alloc(parser->rr_region,
525						 $1.len + $3.len + 1);
526	    memcpy(result, $1.str, $1.len);
527	    memcpy(result + $1.len, $3.str, $3.len);
528	    $$.str = result;
529	    $$.len = $1.len + $3.len;
530	    $$.str[$$.len] = '\0';
531    }
532    ;
533
534/*
535 * A string that can contain dots.
536 */
537unquoted_dotted_str:	STR
538    |	'.'
539    {
540	$$.str = ".";
541	$$.len = 1;
542    }
543    |	unquoted_dotted_str '.'
544    {
545	    char *result = (char *) region_alloc(parser->rr_region,
546						 $1.len + 2);
547	    memcpy(result, $1.str, $1.len);
548	    result[$1.len] = '.';
549	    $$.str = result;
550	    $$.len = $1.len + 1;
551	    $$.str[$$.len] = '\0';
552    }
553    |	unquoted_dotted_str '.' STR
554    {
555	    char *result = (char *) region_alloc(parser->rr_region,
556						 $1.len + $3.len + 2);
557	    memcpy(result, $1.str, $1.len);
558	    result[$1.len] = '.';
559	    memcpy(result + $1.len + 1, $3.str, $3.len);
560	    $$.str = result;
561	    $$.len = $1.len + $3.len + 1;
562	    $$.str[$$.len] = '\0';
563    }
564    ;
565
566/*
567 * A string that can contain dots or a quoted string.
568 */
569dotted_str:	unquoted_dotted_str | QSTR
570
571/* define what we can parse */
572type_and_rdata:
573    /*
574     * All supported RR types.	We don't support NULL and types marked obsolete.
575     */
576    	T_A sp rdata_a
577    |	T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
578    |	T_NS sp rdata_domain_name
579    |	T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
580    |	T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); }
581    |	T_MD sp rdata_unknown
582    {
583	    zc_warning_prev_line("MD is obsolete");
584	    $$ = $1; parse_unknown_rdata($1, $3);
585    }
586    |	T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); }
587    |	T_MF sp rdata_unknown
588    {
589	    zc_warning_prev_line("MF is obsolete");
590	    $$ = $1;
591	    parse_unknown_rdata($1, $3);
592    }
593    |	T_CNAME sp rdata_domain_name
594    |	T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
595    |	T_SOA sp rdata_soa
596    |	T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
597    |	T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); }
598    |	T_MB sp rdata_unknown
599    {
600	    zc_warning_prev_line("MB is obsolete");
601	    $$ = $1;
602	    parse_unknown_rdata($1, $3);
603    }
604    |	T_MG sp rdata_domain_name
605    |	T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
606    |	T_MR sp rdata_domain_name
607    |	T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
608      /* NULL */
609    |	T_WKS sp rdata_wks
610    |	T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
611    |	T_PTR sp rdata_domain_name
612    |	T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
613    |	T_HINFO sp rdata_hinfo
614    |	T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
615    |	T_MINFO sp rdata_minfo /* Experimental */
616    |	T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
617    |	T_MX sp rdata_mx
618    |	T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
619    |	T_TXT sp rdata_txt
620    |	T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
621    |	T_SPF sp rdata_txt
622    |	T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
623    |	T_AVC sp rdata_txt
624    |	T_AVC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
625    |	T_RP sp rdata_rp		/* RFC 1183 */
626    |	T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
627    |	T_AFSDB sp rdata_afsdb	/* RFC 1183 */
628    |	T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
629    |	T_X25 sp rdata_x25	/* RFC 1183 */
630    |	T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
631    |	T_ISDN sp rdata_isdn	/* RFC 1183 */
632    |	T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
633    |	T_IPSECKEY sp rdata_ipseckey	/* RFC 4025 */
634    |	T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
635    |	T_DHCID sp rdata_dhcid
636    |	T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
637    |	T_RT sp rdata_rt		/* RFC 1183 */
638    |	T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
639    |	T_NSAP sp rdata_nsap	/* RFC 1706 */
640    |	T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
641    |	T_SIG sp rdata_rrsig
642    |	T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
643    |	T_KEY sp rdata_dnskey
644    |	T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
645    |	T_PX sp rdata_px		/* RFC 2163 */
646    |	T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
647    |	T_AAAA sp rdata_aaaa
648    |	T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
649    |	T_LOC sp rdata_loc
650    |	T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
651    |	T_NXT sp rdata_nxt
652    |	T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
653    |	T_SRV sp rdata_srv
654    |	T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
655    |	T_NAPTR sp rdata_naptr	/* RFC 2915 */
656    |	T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
657    |	T_KX sp rdata_kx		/* RFC 2230 */
658    |	T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
659    |	T_CERT sp rdata_cert	/* RFC 2538 */
660    |	T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
661    |	T_DNAME sp rdata_domain_name /* RFC 2672 */
662    |	T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
663    |	T_APL trail		/* RFC 3123 */
664    |	T_APL sp rdata_apl	/* RFC 3123 */
665    |	T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
666    |	T_DS sp rdata_ds
667    |	T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
668    |	T_DLV sp rdata_dlv { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } }
669    |	T_DLV sp rdata_unknown { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } $$ = $1; parse_unknown_rdata($1, $3); }
670    |	T_SSHFP sp rdata_sshfp
671    |	T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); check_sshfp(); }
672    |	T_RRSIG sp rdata_rrsig
673    |	T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
674    |	T_NSEC sp rdata_nsec
675    |	T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
676    |	T_NSEC3 sp rdata_nsec3
677    |	T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
678    |	T_NSEC3PARAM sp rdata_nsec3_param
679    |	T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
680    |	T_DNSKEY sp rdata_dnskey
681    |	T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
682    |	T_TLSA sp rdata_tlsa
683    |	T_TLSA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
684    |	T_SMIMEA sp rdata_smimea
685    |	T_SMIMEA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
686    |	T_NID sp rdata_nid
687    |	T_NID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
688    |	T_L32 sp rdata_l32
689    |	T_L32 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
690    |	T_L64 sp rdata_l64
691    |	T_L64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
692    |	T_LP sp rdata_lp
693    |	T_LP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
694    |	T_EUI48 sp rdata_eui48
695    |	T_EUI48 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
696    |	T_EUI64 sp rdata_eui64
697    |	T_EUI64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
698    |	T_CAA sp rdata_caa
699    |	T_CAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
700    |	T_CDS sp rdata_ds
701    |	T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
702    |	T_CDNSKEY sp rdata_dnskey
703    |	T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
704    |	T_OPENPGPKEY sp rdata_openpgpkey
705    |	T_OPENPGPKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
706    |	T_CSYNC sp rdata_csync
707    |	T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
708    |	T_ZONEMD sp rdata_zonemd
709    |	T_ZONEMD sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
710    |	T_SVCB sp rdata_svcb
711    |	T_SVCB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
712    |	T_HTTPS sp rdata_svcb
713    |	T_HTTPS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
714    |	T_URI sp rdata_uri
715    |	T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
716    |	T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
717    |	str error NL
718    {
719	    zc_error_prev_line("unrecognized RR type '%s'", $1.str);
720    }
721    ;
722
723/*
724 *
725 * below are all the definition for all the different rdata
726 *
727 */
728
729rdata_a:	dotted_str trail
730    {
731	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str));
732    }
733    ;
734
735rdata_domain_name:	dname trail
736    {
737	    /* convert a single dname record */
738	    zadd_rdata_domain($1);
739    }
740    ;
741
742rdata_soa:	dname sp dname sp str sp str sp str sp str sp str trail
743    {
744	    /* convert the soa data */
745	    zadd_rdata_domain($1);	/* prim. ns */
746	    zadd_rdata_domain($3);	/* email */
747	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */
748	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */
749	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */
750	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */
751	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */
752    }
753    ;
754
755rdata_wks:	dotted_str sp str sp concatenated_str_seq trail
756    {
757	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */
758	    zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */
759    }
760    ;
761
762rdata_hinfo:	str sp str trail
763    {
764	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */
765	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/
766    }
767    ;
768
769rdata_minfo:	dname sp dname trail
770    {
771	    /* convert a single dname record */
772	    zadd_rdata_domain($1);
773	    zadd_rdata_domain($3);
774    }
775    ;
776
777rdata_mx:	str sp dname trail
778    {
779	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* priority */
780	    zadd_rdata_domain($3);	/* MX host */
781    }
782    ;
783
784rdata_txt:	str_seq trail
785    {
786	zadd_rdata_txt_clean_wireformat();
787    }
788    ;
789
790/* RFC 1183 */
791rdata_rp:	dname sp dname trail
792    {
793	    zadd_rdata_domain($1); /* mbox d-name */
794	    zadd_rdata_domain($3); /* txt d-name */
795    }
796    ;
797
798/* RFC 1183 */
799rdata_afsdb:	str sp dname trail
800    {
801	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */
802	    zadd_rdata_domain($3); /* domain name */
803    }
804    ;
805
806/* RFC 1183 */
807rdata_x25:	str trail
808    {
809	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */
810    }
811    ;
812
813/* RFC 1183 */
814rdata_isdn:	str trail
815    {
816	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
817    }
818    |	str sp str trail
819    {
820	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
821	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */
822    }
823    ;
824
825/* RFC 1183 */
826rdata_rt:	str sp dname trail
827    {
828	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
829	    zadd_rdata_domain($3); /* intermediate host */
830    }
831    ;
832
833/* RFC 1706 */
834rdata_nsap:	str_dot_seq trail
835    {
836	    /* String must start with "0x" or "0X".	 */
837	    if (strncasecmp($1.str, "0x", 2) != 0) {
838		    zc_error_prev_line("NSAP rdata must start with '0x'");
839	    } else {
840		    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */
841	    }
842    }
843    ;
844
845/* RFC 2163 */
846rdata_px:	str sp dname sp dname trail
847    {
848	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
849	    zadd_rdata_domain($3); /* MAP822 */
850	    zadd_rdata_domain($5); /* MAPX400 */
851    }
852    ;
853
854rdata_aaaa:	dotted_str trail
855    {
856	    zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str));  /* IPv6 address */
857    }
858    ;
859
860rdata_loc:	concatenated_str_seq trail
861    {
862	    zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */
863    }
864    ;
865
866rdata_nxt:	dname sp nxt_seq trail
867    {
868	    zadd_rdata_domain($1); /* nxt name */
869	    zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */
870	    memset(nxtbits, 0, sizeof(nxtbits));
871    }
872    ;
873
874rdata_srv:	str sp str sp str sp dname trail
875    {
876	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */
877	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
878	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */
879	    zadd_rdata_domain($7); /* target name */
880    }
881    ;
882
883/* RFC 2915 */
884rdata_naptr:	str sp str sp str sp str sp str sp dname trail
885    {
886	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */
887	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */
888	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */
889	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */
890	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */
891	    zadd_rdata_domain($11); /* target name */
892    }
893    ;
894
895/* RFC 2230 */
896rdata_kx:	str sp dname trail
897    {
898	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
899	    zadd_rdata_domain($3); /* exchanger */
900    }
901    ;
902
903/* RFC 2538 */
904rdata_cert:	str sp str sp str sp str_sp_seq trail
905    {
906	    zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */
907	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */
908	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */
909	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */
910    }
911    ;
912
913/* RFC 3123 */
914rdata_apl:	rdata_apl_seq trail
915    ;
916
917rdata_apl_seq:	dotted_str
918    {
919	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str));
920    }
921    |	rdata_apl_seq sp dotted_str
922    {
923	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str));
924    }
925    ;
926
927rdata_ds:	str sp str sp str sp str_sp_seq trail
928    {
929	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
930	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
931	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
932	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
933    }
934    ;
935
936rdata_dlv:	str sp str sp str sp str_sp_seq trail
937    {
938	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
939	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
940	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
941	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
942    }
943    ;
944
945rdata_sshfp:	str sp str sp str_sp_seq trail
946    {
947	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */
948	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */
949	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */
950	    check_sshfp();
951    }
952    ;
953
954rdata_dhcid:	str_sp_seq trail
955    {
956	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */
957    }
958    ;
959
960rdata_rrsig:	str sp str sp str sp str sp str sp str sp str sp wire_dname sp str_sp_seq trail
961    {
962	    zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */
963	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
964	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */
965	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */
966	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */
967	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */
968	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */
969	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
970				(const uint8_t*) $15.str,$15.len)); /* sig name */
971	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */
972    }
973    ;
974
975rdata_nsec:	wire_dname nsec_seq
976    {
977	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
978				(const uint8_t*) $1.str, $1.len)); /* nsec name */
979	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
980	    memset(nsecbits, 0, sizeof(nsecbits));
981            nsec_highest_rcode = 0;
982    }
983    ;
984
985rdata_nsec3:   str sp str sp str sp str sp str nsec_seq
986    {
987#ifdef NSEC3
988	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
989
990	    zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */
991	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
992	    memset(nsecbits, 0, sizeof(nsecbits));
993	    nsec_highest_rcode = 0;
994#else
995	    zc_error_prev_line("nsec3 not supported");
996#endif /* NSEC3 */
997    }
998    ;
999
1000rdata_nsec3_param:   str sp str sp str sp str trail
1001    {
1002#ifdef NSEC3
1003	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
1004#else
1005	    zc_error_prev_line("nsec3 not supported");
1006#endif /* NSEC3 */
1007    }
1008    ;
1009
1010rdata_tlsa:	str sp str sp str sp str_sp_seq trail
1011    {
1012	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1013	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1014	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1015	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1016    }
1017    ;
1018
1019rdata_smimea:	str sp str sp str sp str_sp_seq trail
1020    {
1021	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1022	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1023	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1024	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1025    }
1026    ;
1027
1028rdata_dnskey:	str sp str sp str sp str_sp_seq trail
1029    {
1030	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */
1031	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */
1032	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */
1033	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */
1034    }
1035    ;
1036
1037rdata_ipsec_base: str sp str sp str sp dotted_str
1038    {
1039	    const dname_type* name = 0;
1040	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */
1041	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */
1042	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */
1043	    switch(atoi($3.str)) {
1044		case IPSECKEY_NOGATEWAY:
1045			zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0));
1046			break;
1047		case IPSECKEY_IP4:
1048			zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str));
1049			break;
1050		case IPSECKEY_IP6:
1051			zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $7.str));
1052			break;
1053		case IPSECKEY_DNAME:
1054			/* convert and insert the dname */
1055			if(strlen($7.str) == 0)
1056				zc_error_prev_line("IPSECKEY must specify gateway name");
1057			if(!(name = dname_parse(parser->region, $7.str))) {
1058				zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str);
1059				break;
1060			}
1061			if($7.str[strlen($7.str)-1] != '.') {
1062				if(parser->origin == error_domain) {
1063		    			zc_error("cannot concatenate origin to domain name, because origin failed to parse");
1064					break;
1065				} else if(name->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) {
1066					zc_error("ipsec gateway name exceeds %d character limit",
1067						MAXDOMAINLEN);
1068					break;
1069				}
1070				name = dname_concatenate(parser->rr_region, name,
1071					domain_dname(parser->origin));
1072			}
1073			zadd_rdata_wireformat(alloc_rdata_init(parser->region,
1074				dname_name(name), name->name_size));
1075			break;
1076		default:
1077			zc_error_prev_line("unknown IPSECKEY gateway type");
1078	    }
1079    }
1080    ;
1081
1082rdata_ipseckey:	rdata_ipsec_base sp str_sp_seq trail
1083    {
1084	   zadd_rdata_wireformat(zparser_conv_b64(parser->region, $3.str)); /* public key */
1085    }
1086    | rdata_ipsec_base trail
1087    ;
1088
1089/* RFC 6742 */
1090rdata_nid:	str sp dotted_str trail
1091    {
1092	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1093	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* NodeID */
1094    }
1095    ;
1096
1097rdata_l32:	str sp dotted_str trail
1098    {
1099	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1100	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str));  /* Locator32 */
1101    }
1102    ;
1103
1104rdata_l64:	str sp dotted_str trail
1105    {
1106	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1107	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* Locator64 */
1108    }
1109    ;
1110
1111rdata_lp:	str sp dname trail
1112    {
1113	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1114	    zadd_rdata_domain($3);  /* FQDN */
1115    }
1116    ;
1117
1118rdata_eui48:	str trail
1119    {
1120	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
1121    }
1122    ;
1123
1124rdata_eui64:	str trail
1125    {
1126	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
1127    }
1128    ;
1129
1130/* RFC7553 */
1131rdata_uri:	str sp str sp dotted_str trail
1132    {
1133	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
1134	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
1135	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */
1136    }
1137    ;
1138
1139/* RFC 6844 */
1140rdata_caa:	str sp str sp dotted_str trail
1141    {
1142	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */
1143	    zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */
1144	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */
1145    }
1146    ;
1147
1148/* RFC7929 */
1149rdata_openpgpkey:	str_sp_seq trail
1150    {
1151	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str));
1152    }
1153    ;
1154
1155/* RFC7477 */
1156rdata_csync:	str sp str nsec_seq
1157    {
1158	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str));
1159	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str));
1160	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
1161	    memset(nsecbits, 0, sizeof(nsecbits));
1162            nsec_highest_rcode = 0;
1163    }
1164    ;
1165
1166/* draft-ietf-dnsop-dns-zone-digest */
1167rdata_zonemd:	str sp str sp str sp str_sp_seq trail
1168    {
1169	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); /* serial */
1170	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* scheme */
1171	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* hash algorithm */
1172	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* digest */
1173    }
1174    ;
1175
1176svcparam:	dotted_str QSTR
1177    {
1178	zadd_rdata_wireformat(zparser_conv_svcbparam(
1179		parser->region, $1.str, $1.len, $2.str, $2.len));
1180    }
1181    |		dotted_str
1182    {
1183	zadd_rdata_wireformat(zparser_conv_svcbparam(
1184		parser->region, $1.str, $1.len, NULL, 0));
1185    }
1186    ;
1187svcparams:	svcparam
1188    |		svcparams sp svcparam
1189    ;
1190/* draft-ietf-dnsop-svcb-https */
1191rdata_svcb_base:	str sp dname
1192    {
1193	    /* SvcFieldPriority */
1194	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));
1195	    /* SvcDomainName */
1196	    zadd_rdata_domain($3);
1197    };
1198rdata_svcb:     rdata_svcb_base sp svcparams trail
1199    {
1200        zadd_rdata_svcb_check_wireformat();
1201    }
1202    |   rdata_svcb_base trail
1203    ;
1204
1205rdata_unknown:	URR sp str sp str_sp_seq trail
1206    {
1207	    /* $2 is the number of octets, currently ignored */
1208	    $$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len);
1209
1210    }
1211    |	URR sp str trail
1212    {
1213	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1214    }
1215    |	URR error NL
1216    {
1217	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1218    }
1219    ;
1220%%
1221
1222int
1223yywrap(void)
1224{
1225	return 1;
1226}
1227
1228/*
1229 * Create the parser.
1230 */
1231zparser_type *
1232zparser_create(region_type *region, region_type *rr_region, namedb_type *db)
1233{
1234	zparser_type *result;
1235
1236	result = (zparser_type *) region_alloc(region, sizeof(zparser_type));
1237	result->region = region;
1238	result->rr_region = rr_region;
1239	result->db = db;
1240
1241	result->filename = NULL;
1242	result->current_zone = NULL;
1243	result->origin = NULL;
1244	result->prev_dname = NULL;
1245
1246	result->temporary_rdatas = (rdata_atom_type *) region_alloc_array(
1247		result->region, MAXRDATALEN, sizeof(rdata_atom_type));
1248
1249	return result;
1250}
1251
1252/*
1253 * Initialize the parser for a new zone file.
1254 */
1255void
1256zparser_init(const char *filename, uint32_t ttl, uint16_t klass,
1257	     const dname_type *origin)
1258{
1259	memset(nxtbits, 0, sizeof(nxtbits));
1260	memset(nsecbits, 0, sizeof(nsecbits));
1261        nsec_highest_rcode = 0;
1262
1263	parser->default_ttl = ttl;
1264	parser->default_class = klass;
1265	parser->current_zone = NULL;
1266	parser->origin = domain_table_insert(parser->db->domains, origin);
1267	parser->prev_dname = parser->origin;
1268	parser->error_occurred = 0;
1269	parser->errors = 0;
1270	parser->line = 1;
1271	parser->filename = filename;
1272	parser->current_rr.rdata_count = 0;
1273	parser->current_rr.rdatas = parser->temporary_rdatas;
1274}
1275
1276void
1277yyerror(const char *message)
1278{
1279	zc_error("%s", message);
1280}
1281
1282static void
1283error_va_list(unsigned line, const char *fmt, va_list args)
1284{
1285	if (parser->filename) {
1286		char message[MAXSYSLOGMSGLEN];
1287		vsnprintf(message, sizeof(message), fmt, args);
1288		log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message);
1289	}
1290	else log_vmsg(LOG_ERR, fmt, args);
1291
1292	++parser->errors;
1293	parser->error_occurred = 1;
1294}
1295
1296/* the line counting sux, to say the least
1297 * with this grose hack we try do give sane
1298 * numbers back */
1299void
1300zc_error_prev_line(const char *fmt, ...)
1301{
1302	va_list args;
1303	va_start(args, fmt);
1304	error_va_list(parser->line - 1, fmt, args);
1305	va_end(args);
1306}
1307
1308void
1309zc_error(const char *fmt, ...)
1310{
1311	/* send an error message to stderr */
1312	va_list args;
1313	va_start(args, fmt);
1314	error_va_list(parser->line, fmt, args);
1315	va_end(args);
1316}
1317
1318static void
1319warning_va_list(unsigned line, const char *fmt, va_list args)
1320{
1321	if (parser->filename) {
1322		char m[MAXSYSLOGMSGLEN];
1323		vsnprintf(m, sizeof(m), fmt, args);
1324		log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m);
1325	}
1326	else log_vmsg(LOG_WARNING, fmt, args);
1327}
1328
1329void
1330zc_warning_prev_line(const char *fmt, ...)
1331{
1332	va_list args;
1333	va_start(args, fmt);
1334	warning_va_list(parser->line - 1, fmt, args);
1335	va_end(args);
1336}
1337
1338void
1339zc_warning(const char *fmt, ... )
1340{
1341	va_list args;
1342	va_start(args, fmt);
1343	warning_va_list(parser->line, fmt, args);
1344	va_end(args);
1345}
1346
1347#ifdef NSEC3
1348static void
1349nsec3_add_params(const char* hashalgo_str, const char* flag_str,
1350	const char* iter_str, const char* salt_str, int salt_len)
1351{
1352	zadd_rdata_wireformat(zparser_conv_byte(parser->region, hashalgo_str));
1353	zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str));
1354	zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str));
1355
1356	/* salt */
1357	if(strcmp(salt_str, "-") != 0)
1358		zadd_rdata_wireformat(zparser_conv_hex_length(parser->region,
1359			salt_str, salt_len));
1360	else
1361		zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1));
1362}
1363#endif /* NSEC3 */
1364