xref: /openbsd/usr.sbin/nsd/zparser.y (revision 771fbea0)
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>  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
89 %type <data>	nxt_seq nsec_more
90 %type <unknown> rdata_unknown
91 
92 %%
93 lines:	/* empty file */
94     |	lines line
95     ;
96 
97 line:	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 */
140 sp:	SP
141     |	sp SP
142     ;
143 
144 str:	STR | QSTR;
145 
146 trail:	NL
147     |	sp NL
148     ;
149 
150 ttl_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 
160 origin_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 
177 rr:	owner classttl type_and_rdata
178     {
179 	    parser->current_rr.owner = $1;
180 	    parser->current_rr.type = $3;
181     }
182     ;
183 
184 owner:	dname sp
185     {
186 	    parser->prev_dname = $1;
187 	    $$ = $1;
188     }
189     |	PREV
190     {
191 	    $$ = parser->prev_dname;
192     }
193     ;
194 
195 classttl:	/* 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 
222 dname:	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 
244 abs_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 
262 label:	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 
283 rel_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 
302 wire_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 
327 wire_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 
358 wire_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 
375 wire_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 
388 str_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  */
429 concatenated_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 */
456 nxt_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 
476 nsec_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 
496 nsec_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  */
504 str_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  */
521 str_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  */
537 unquoted_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  */
569 dotted_str:	unquoted_dotted_str | QSTR
570 
571 /* define what we can parse */
572 type_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_URI sp rdata_uri
711     |	T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
712     |	T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
713     |	str error NL
714     {
715 	    zc_error_prev_line("unrecognized RR type '%s'", $1.str);
716     }
717     ;
718 
719 /*
720  *
721  * below are all the definition for all the different rdata
722  *
723  */
724 
725 rdata_a:	dotted_str trail
726     {
727 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str));
728     }
729     ;
730 
731 rdata_domain_name:	dname trail
732     {
733 	    /* convert a single dname record */
734 	    zadd_rdata_domain($1);
735     }
736     ;
737 
738 rdata_soa:	dname sp dname sp str sp str sp str sp str sp str trail
739     {
740 	    /* convert the soa data */
741 	    zadd_rdata_domain($1);	/* prim. ns */
742 	    zadd_rdata_domain($3);	/* email */
743 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */
744 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */
745 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */
746 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */
747 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */
748     }
749     ;
750 
751 rdata_wks:	dotted_str sp str sp concatenated_str_seq trail
752     {
753 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */
754 	    zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */
755     }
756     ;
757 
758 rdata_hinfo:	str sp str trail
759     {
760 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */
761 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/
762     }
763     ;
764 
765 rdata_minfo:	dname sp dname trail
766     {
767 	    /* convert a single dname record */
768 	    zadd_rdata_domain($1);
769 	    zadd_rdata_domain($3);
770     }
771     ;
772 
773 rdata_mx:	str sp dname trail
774     {
775 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* priority */
776 	    zadd_rdata_domain($3);	/* MX host */
777     }
778     ;
779 
780 rdata_txt:	str_seq trail
781     {
782 	zadd_rdata_txt_clean_wireformat();
783     }
784     ;
785 
786 /* RFC 1183 */
787 rdata_rp:	dname sp dname trail
788     {
789 	    zadd_rdata_domain($1); /* mbox d-name */
790 	    zadd_rdata_domain($3); /* txt d-name */
791     }
792     ;
793 
794 /* RFC 1183 */
795 rdata_afsdb:	str sp dname trail
796     {
797 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */
798 	    zadd_rdata_domain($3); /* domain name */
799     }
800     ;
801 
802 /* RFC 1183 */
803 rdata_x25:	str trail
804     {
805 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */
806     }
807     ;
808 
809 /* RFC 1183 */
810 rdata_isdn:	str trail
811     {
812 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
813     }
814     |	str sp str trail
815     {
816 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
817 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */
818     }
819     ;
820 
821 /* RFC 1183 */
822 rdata_rt:	str sp dname trail
823     {
824 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
825 	    zadd_rdata_domain($3); /* intermediate host */
826     }
827     ;
828 
829 /* RFC 1706 */
830 rdata_nsap:	str_dot_seq trail
831     {
832 	    /* String must start with "0x" or "0X".	 */
833 	    if (strncasecmp($1.str, "0x", 2) != 0) {
834 		    zc_error_prev_line("NSAP rdata must start with '0x'");
835 	    } else {
836 		    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */
837 	    }
838     }
839     ;
840 
841 /* RFC 2163 */
842 rdata_px:	str sp dname sp dname trail
843     {
844 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
845 	    zadd_rdata_domain($3); /* MAP822 */
846 	    zadd_rdata_domain($5); /* MAPX400 */
847     }
848     ;
849 
850 rdata_aaaa:	dotted_str trail
851     {
852 	    zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str));  /* IPv6 address */
853     }
854     ;
855 
856 rdata_loc:	concatenated_str_seq trail
857     {
858 	    zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */
859     }
860     ;
861 
862 rdata_nxt:	dname sp nxt_seq trail
863     {
864 	    zadd_rdata_domain($1); /* nxt name */
865 	    zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */
866 	    memset(nxtbits, 0, sizeof(nxtbits));
867     }
868     ;
869 
870 rdata_srv:	str sp str sp str sp dname trail
871     {
872 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */
873 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
874 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */
875 	    zadd_rdata_domain($7); /* target name */
876     }
877     ;
878 
879 /* RFC 2915 */
880 rdata_naptr:	str sp str sp str sp str sp str sp dname trail
881     {
882 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */
883 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */
884 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */
885 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */
886 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */
887 	    zadd_rdata_domain($11); /* target name */
888     }
889     ;
890 
891 /* RFC 2230 */
892 rdata_kx:	str sp dname trail
893     {
894 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
895 	    zadd_rdata_domain($3); /* exchanger */
896     }
897     ;
898 
899 /* RFC 2538 */
900 rdata_cert:	str sp str sp str sp str_sp_seq trail
901     {
902 	    zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */
903 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */
904 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */
905 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */
906     }
907     ;
908 
909 /* RFC 3123 */
910 rdata_apl:	rdata_apl_seq trail
911     ;
912 
913 rdata_apl_seq:	dotted_str
914     {
915 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str));
916     }
917     |	rdata_apl_seq sp dotted_str
918     {
919 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str));
920     }
921     ;
922 
923 rdata_ds:	str sp str sp str sp str_sp_seq trail
924     {
925 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
926 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
927 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
928 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
929     }
930     ;
931 
932 rdata_dlv:	str sp str sp str sp str_sp_seq trail
933     {
934 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
935 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
936 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
937 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
938     }
939     ;
940 
941 rdata_sshfp:	str sp str sp str_sp_seq trail
942     {
943 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */
944 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */
945 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */
946 	    check_sshfp();
947     }
948     ;
949 
950 rdata_dhcid:	str_sp_seq trail
951     {
952 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */
953     }
954     ;
955 
956 rdata_rrsig:	str sp str sp str sp str sp str sp str sp str sp wire_dname sp str_sp_seq trail
957     {
958 	    zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */
959 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
960 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */
961 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */
962 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */
963 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */
964 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */
965 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
966 				(const uint8_t*) $15.str,$15.len)); /* sig name */
967 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */
968     }
969     ;
970 
971 rdata_nsec:	wire_dname nsec_seq
972     {
973 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
974 				(const uint8_t*) $1.str, $1.len)); /* nsec name */
975 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
976 	    memset(nsecbits, 0, sizeof(nsecbits));
977             nsec_highest_rcode = 0;
978     }
979     ;
980 
981 rdata_nsec3:   str sp str sp str sp str sp str nsec_seq
982     {
983 #ifdef NSEC3
984 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
985 
986 	    zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */
987 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
988 	    memset(nsecbits, 0, sizeof(nsecbits));
989 	    nsec_highest_rcode = 0;
990 #else
991 	    zc_error_prev_line("nsec3 not supported");
992 #endif /* NSEC3 */
993     }
994     ;
995 
996 rdata_nsec3_param:   str sp str sp str sp str trail
997     {
998 #ifdef NSEC3
999 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
1000 #else
1001 	    zc_error_prev_line("nsec3 not supported");
1002 #endif /* NSEC3 */
1003     }
1004     ;
1005 
1006 rdata_tlsa:	str sp str sp str sp str_sp_seq trail
1007     {
1008 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1009 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1010 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1011 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1012     }
1013     ;
1014 
1015 rdata_smimea:	str sp str sp str sp str_sp_seq trail
1016     {
1017 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1018 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1019 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1020 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1021     }
1022     ;
1023 
1024 rdata_dnskey:	str sp str sp str sp str_sp_seq trail
1025     {
1026 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */
1027 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */
1028 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */
1029 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */
1030     }
1031     ;
1032 
1033 rdata_ipsec_base: str sp str sp str sp dotted_str
1034     {
1035 	    const dname_type* name = 0;
1036 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */
1037 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */
1038 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */
1039 	    switch(atoi($3.str)) {
1040 		case IPSECKEY_NOGATEWAY:
1041 			zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0));
1042 			break;
1043 		case IPSECKEY_IP4:
1044 			zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str));
1045 			break;
1046 		case IPSECKEY_IP6:
1047 			zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $7.str));
1048 			break;
1049 		case IPSECKEY_DNAME:
1050 			/* convert and insert the dname */
1051 			if(strlen($7.str) == 0)
1052 				zc_error_prev_line("IPSECKEY must specify gateway name");
1053 			if(!(name = dname_parse(parser->region, $7.str))) {
1054 				zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str);
1055 				break;
1056 			}
1057 			if($7.str[strlen($7.str)-1] != '.') {
1058 				if(parser->origin == error_domain) {
1059 		    			zc_error("cannot concatenate origin to domain name, because origin failed to parse");
1060 					break;
1061 				} else if(name->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) {
1062 					zc_error("ipsec gateway name exceeds %d character limit",
1063 						MAXDOMAINLEN);
1064 					break;
1065 				}
1066 				name = dname_concatenate(parser->rr_region, name,
1067 					domain_dname(parser->origin));
1068 			}
1069 			zadd_rdata_wireformat(alloc_rdata_init(parser->region,
1070 				dname_name(name), name->name_size));
1071 			break;
1072 		default:
1073 			zc_error_prev_line("unknown IPSECKEY gateway type");
1074 	    }
1075     }
1076     ;
1077 
1078 rdata_ipseckey:	rdata_ipsec_base sp str_sp_seq trail
1079     {
1080 	   zadd_rdata_wireformat(zparser_conv_b64(parser->region, $3.str)); /* public key */
1081     }
1082     | rdata_ipsec_base trail
1083     ;
1084 
1085 /* RFC 6742 */
1086 rdata_nid:	str sp dotted_str trail
1087     {
1088 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1089 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* NodeID */
1090     }
1091     ;
1092 
1093 rdata_l32:	str sp dotted_str trail
1094     {
1095 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1096 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str));  /* Locator32 */
1097     }
1098     ;
1099 
1100 rdata_l64:	str sp dotted_str trail
1101     {
1102 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1103 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* Locator64 */
1104     }
1105     ;
1106 
1107 rdata_lp:	str sp dname trail
1108     {
1109 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1110 	    zadd_rdata_domain($3);  /* FQDN */
1111     }
1112     ;
1113 
1114 rdata_eui48:	str trail
1115     {
1116 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
1117     }
1118     ;
1119 
1120 rdata_eui64:	str trail
1121     {
1122 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
1123     }
1124     ;
1125 
1126 /* RFC7553 */
1127 rdata_uri:	str sp str sp dotted_str trail
1128     {
1129 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
1130 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
1131 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */
1132     }
1133     ;
1134 
1135 /* RFC 6844 */
1136 rdata_caa:	str sp str sp dotted_str trail
1137     {
1138 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */
1139 	    zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */
1140 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */
1141     }
1142     ;
1143 
1144 /* RFC7929 */
1145 rdata_openpgpkey:	str_sp_seq trail
1146     {
1147 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str));
1148     }
1149     ;
1150 
1151 /* RFC7477 */
1152 rdata_csync:	str sp str nsec_seq
1153     {
1154 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str));
1155 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str));
1156 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
1157 	    memset(nsecbits, 0, sizeof(nsecbits));
1158             nsec_highest_rcode = 0;
1159     }
1160     ;
1161 
1162 /* draft-ietf-dnsop-dns-zone-digest */
1163 rdata_zonemd:	str sp str sp str sp str_sp_seq trail
1164     {
1165 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); /* serial */
1166 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* scheme */
1167 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* hash algorithm */
1168 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* digest */
1169     }
1170     ;
1171 
1172 rdata_unknown:	URR sp str sp str_sp_seq trail
1173     {
1174 	    /* $2 is the number of octets, currently ignored */
1175 	    $$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len);
1176 
1177     }
1178     |	URR sp str trail
1179     {
1180 	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1181     }
1182     |	URR error NL
1183     {
1184 	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1185     }
1186     ;
1187 %%
1188 
1189 int
1190 yywrap(void)
1191 {
1192 	return 1;
1193 }
1194 
1195 /*
1196  * Create the parser.
1197  */
1198 zparser_type *
1199 zparser_create(region_type *region, region_type *rr_region, namedb_type *db)
1200 {
1201 	zparser_type *result;
1202 
1203 	result = (zparser_type *) region_alloc(region, sizeof(zparser_type));
1204 	result->region = region;
1205 	result->rr_region = rr_region;
1206 	result->db = db;
1207 
1208 	result->filename = NULL;
1209 	result->current_zone = NULL;
1210 	result->origin = NULL;
1211 	result->prev_dname = NULL;
1212 
1213 	result->temporary_rdatas = (rdata_atom_type *) region_alloc_array(
1214 		result->region, MAXRDATALEN, sizeof(rdata_atom_type));
1215 
1216 	return result;
1217 }
1218 
1219 /*
1220  * Initialize the parser for a new zone file.
1221  */
1222 void
1223 zparser_init(const char *filename, uint32_t ttl, uint16_t klass,
1224 	     const dname_type *origin)
1225 {
1226 	memset(nxtbits, 0, sizeof(nxtbits));
1227 	memset(nsecbits, 0, sizeof(nsecbits));
1228         nsec_highest_rcode = 0;
1229 
1230 	parser->default_ttl = ttl;
1231 	parser->default_class = klass;
1232 	parser->current_zone = NULL;
1233 	parser->origin = domain_table_insert(parser->db->domains, origin);
1234 	parser->prev_dname = parser->origin;
1235 	parser->error_occurred = 0;
1236 	parser->errors = 0;
1237 	parser->line = 1;
1238 	parser->filename = filename;
1239 	parser->current_rr.rdata_count = 0;
1240 	parser->current_rr.rdatas = parser->temporary_rdatas;
1241 }
1242 
1243 void
1244 yyerror(const char *message)
1245 {
1246 	zc_error("%s", message);
1247 }
1248 
1249 static void
1250 error_va_list(unsigned line, const char *fmt, va_list args)
1251 {
1252 	if (parser->filename) {
1253 		char message[MAXSYSLOGMSGLEN];
1254 		vsnprintf(message, sizeof(message), fmt, args);
1255 		log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message);
1256 	}
1257 	else log_vmsg(LOG_ERR, fmt, args);
1258 
1259 	++parser->errors;
1260 	parser->error_occurred = 1;
1261 }
1262 
1263 /* the line counting sux, to say the least
1264  * with this grose hack we try do give sane
1265  * numbers back */
1266 void
1267 zc_error_prev_line(const char *fmt, ...)
1268 {
1269 	va_list args;
1270 	va_start(args, fmt);
1271 	error_va_list(parser->line - 1, fmt, args);
1272 	va_end(args);
1273 }
1274 
1275 void
1276 zc_error(const char *fmt, ...)
1277 {
1278 	/* send an error message to stderr */
1279 	va_list args;
1280 	va_start(args, fmt);
1281 	error_va_list(parser->line, fmt, args);
1282 	va_end(args);
1283 }
1284 
1285 static void
1286 warning_va_list(unsigned line, const char *fmt, va_list args)
1287 {
1288 	if (parser->filename) {
1289 		char m[MAXSYSLOGMSGLEN];
1290 		vsnprintf(m, sizeof(m), fmt, args);
1291 		log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m);
1292 	}
1293 	else log_vmsg(LOG_WARNING, fmt, args);
1294 }
1295 
1296 void
1297 zc_warning_prev_line(const char *fmt, ...)
1298 {
1299 	va_list args;
1300 	va_start(args, fmt);
1301 	warning_va_list(parser->line - 1, fmt, args);
1302 	va_end(args);
1303 }
1304 
1305 void
1306 zc_warning(const char *fmt, ... )
1307 {
1308 	va_list args;
1309 	va_start(args, fmt);
1310 	warning_va_list(parser->line, fmt, args);
1311 	va_end(args);
1312 }
1313 
1314 #ifdef NSEC3
1315 static void
1316 nsec3_add_params(const char* hashalgo_str, const char* flag_str,
1317 	const char* iter_str, const char* salt_str, int salt_len)
1318 {
1319 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, hashalgo_str));
1320 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str));
1321 	zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str));
1322 
1323 	/* salt */
1324 	if(strcmp(salt_str, "-") != 0)
1325 		zadd_rdata_wireformat(zparser_conv_hex_length(parser->region,
1326 			salt_str, salt_len));
1327 	else
1328 		zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1));
1329 }
1330 #endif /* NSEC3 */
1331