xref: /openbsd/usr.sbin/nsd/zparser.y (revision 5a38ef86)
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 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 %%
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_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 
729 rdata_a:	dotted_str trail
730     {
731 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str));
732     }
733     ;
734 
735 rdata_domain_name:	dname trail
736     {
737 	    /* convert a single dname record */
738 	    zadd_rdata_domain($1);
739     }
740     ;
741 
742 rdata_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 
755 rdata_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 
762 rdata_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 
769 rdata_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 
777 rdata_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 
784 rdata_txt:	str_seq trail
785     {
786 	zadd_rdata_txt_clean_wireformat();
787     }
788     ;
789 
790 /* RFC 1183 */
791 rdata_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 */
799 rdata_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 */
807 rdata_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 */
814 rdata_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 */
826 rdata_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 */
834 rdata_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 */
846 rdata_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 
854 rdata_aaaa:	dotted_str trail
855     {
856 	    zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str));  /* IPv6 address */
857     }
858     ;
859 
860 rdata_loc:	concatenated_str_seq trail
861     {
862 	    zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */
863     }
864     ;
865 
866 rdata_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 
874 rdata_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 */
884 rdata_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 */
896 rdata_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 */
904 rdata_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 */
914 rdata_apl:	rdata_apl_seq trail
915     ;
916 
917 rdata_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 
927 rdata_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 
936 rdata_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 
945 rdata_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 
954 rdata_dhcid:	str_sp_seq trail
955     {
956 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */
957     }
958     ;
959 
960 rdata_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 
975 rdata_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 
985 rdata_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 
1000 rdata_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 
1010 rdata_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 
1019 rdata_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 
1028 rdata_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 
1037 rdata_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 
1082 rdata_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 */
1090 rdata_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 
1097 rdata_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 
1104 rdata_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 
1111 rdata_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 
1118 rdata_eui48:	str trail
1119     {
1120 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
1121     }
1122     ;
1123 
1124 rdata_eui64:	str trail
1125     {
1126 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
1127     }
1128     ;
1129 
1130 /* RFC7553 */
1131 rdata_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 */
1140 rdata_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 */
1149 rdata_openpgpkey:	str_sp_seq trail
1150     {
1151 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str));
1152     }
1153     ;
1154 
1155 /* RFC7477 */
1156 rdata_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 */
1167 rdata_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 
1176 svcparam:	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     ;
1187 svcparams:	svcparam
1188     |		svcparams sp svcparam
1189     ;
1190 /* draft-ietf-dnsop-svcb-https */
1191 rdata_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     };
1198 rdata_svcb:     rdata_svcb_base sp svcparams trail
1199     {
1200         zadd_rdata_svcb_check_wireformat();
1201     }
1202     |   rdata_svcb_base trail
1203     ;
1204 
1205 rdata_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 
1222 int
1223 yywrap(void)
1224 {
1225 	return 1;
1226 }
1227 
1228 /*
1229  * Create the parser.
1230  */
1231 zparser_type *
1232 zparser_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  */
1255 void
1256 zparser_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 
1276 void
1277 yyerror(const char *message)
1278 {
1279 	zc_error("%s", message);
1280 }
1281 
1282 static void
1283 error_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 */
1299 void
1300 zc_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 
1308 void
1309 zc_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 
1318 static void
1319 warning_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 
1329 void
1330 zc_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 
1338 void
1339 zc_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
1348 static void
1349 nsec3_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