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