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