xref: /openbsd-src/usr.sbin/nsd/zparser.y (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
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_CSYNC
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 
303 wire_abs_dname:	'.'
304     {
305 	    char *result = (char *) region_alloc(parser->rr_region, 2);
306 	    result[0] = 0;
307 	    result[1] = '\0';
308 	    $$.str = result;
309 	    $$.len = 1;
310     }
311     |	wire_rel_dname '.'
312     {
313 	    char *result = (char *) region_alloc(parser->rr_region,
314 						 $1.len + 2);
315 	    memcpy(result, $1.str, $1.len);
316 	    result[$1.len] = 0;
317 	    result[$1.len+1] = '\0';
318 	    $$.str = result;
319 	    $$.len = $1.len + 1;
320     }
321     ;
322 
323 wire_label:	STR
324     {
325 	    char *result = (char *) region_alloc(parser->rr_region,
326 						 $1.len + 1);
327 
328 	    if ($1.len > MAXLABELLEN)
329 		    zc_error("label exceeds %d character limit", MAXLABELLEN);
330 
331 	    /* make label anyway */
332 	    result[0] = $1.len;
333 	    memcpy(result+1, $1.str, $1.len);
334 
335 	    $$.str = result;
336 	    $$.len = $1.len + 1;
337     }
338     ;
339 
340 wire_rel_dname:	wire_label
341     |	wire_rel_dname '.' wire_label
342     {
343 	    if ($1.len + $3.len - 3 > MAXDOMAINLEN)
344 		    zc_error("domain name exceeds %d character limit",
345 			     MAXDOMAINLEN);
346 
347 	    /* make dname anyway */
348 	    $$.len = $1.len + $3.len;
349 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
350 	    memcpy($$.str, $1.str, $1.len);
351 	    memcpy($$.str + $1.len, $3.str, $3.len);
352 	    $$.str[$$.len] = '\0';
353     }
354     ;
355 
356 str_seq:	dotted_str
357     {
358 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
359     }
360     |	str_seq sp dotted_str
361     {
362 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
363     }
364     ;
365 
366 /*
367  * Generate a single string from multiple STR tokens, separated by
368  * spaces or dots.
369  */
370 concatenated_str_seq:	STR
371     |	'.'
372     {
373 	    $$.len = 1;
374 	    $$.str = region_strdup(parser->rr_region, ".");
375     }
376     |	concatenated_str_seq sp STR
377     {
378 	    $$.len = $1.len + $3.len + 1;
379 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
380 	    memcpy($$.str, $1.str, $1.len);
381 	    memcpy($$.str + $1.len, " ", 1);
382 	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
383 	    $$.str[$$.len] = '\0';
384     }
385     |	concatenated_str_seq '.' STR
386     {
387 	    $$.len = $1.len + $3.len + 1;
388 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
389 	    memcpy($$.str, $1.str, $1.len);
390 	    memcpy($$.str + $1.len, ".", 1);
391 	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
392 	    $$.str[$$.len] = '\0';
393     }
394     ;
395 
396 /* used to convert a nxt list of types */
397 nxt_seq:	STR
398     {
399 	    uint16_t type = rrtype_from_string($1.str);
400 	    if (type != 0 && type < 128) {
401 		    set_bit(nxtbits, type);
402 	    } else {
403 		    zc_error("bad type %d in NXT record", (int) type);
404 	    }
405     }
406     |	nxt_seq sp STR
407     {
408 	    uint16_t type = rrtype_from_string($3.str);
409 	    if (type != 0 && type < 128) {
410 		    set_bit(nxtbits, type);
411 	    } else {
412 		    zc_error("bad type %d in NXT record", (int) type);
413 	    }
414     }
415     ;
416 
417 nsec_more:	SP nsec_more
418     {
419     }
420     |	NL
421     {
422     }
423     |	STR nsec_seq
424     {
425 	    uint16_t type = rrtype_from_string($1.str);
426 	    if (type != 0) {
427                     if (type > nsec_highest_rcode) {
428                             nsec_highest_rcode = type;
429                     }
430 		    set_bitnsec(nsecbits, type);
431 	    } else {
432 		    zc_error("bad type %d in NSEC record", (int) type);
433 	    }
434     }
435     ;
436 
437 nsec_seq:	NL
438 	|	SP nsec_more
439 	;
440 
441 /*
442  * Sequence of STR tokens separated by spaces.	The spaces are not
443  * preserved during concatenation.
444  */
445 str_sp_seq:	STR
446     |	str_sp_seq sp STR
447     {
448 	    char *result = (char *) region_alloc(parser->rr_region,
449 						 $1.len + $3.len + 1);
450 	    memcpy(result, $1.str, $1.len);
451 	    memcpy(result + $1.len, $3.str, $3.len);
452 	    $$.str = result;
453 	    $$.len = $1.len + $3.len;
454 	    $$.str[$$.len] = '\0';
455     }
456     ;
457 
458 /*
459  * Sequence of STR tokens separated by dots.  The dots are not
460  * preserved during concatenation.
461  */
462 str_dot_seq:	STR
463     |	str_dot_seq '.' STR
464     {
465 	    char *result = (char *) region_alloc(parser->rr_region,
466 						 $1.len + $3.len + 1);
467 	    memcpy(result, $1.str, $1.len);
468 	    memcpy(result + $1.len, $3.str, $3.len);
469 	    $$.str = result;
470 	    $$.len = $1.len + $3.len;
471 	    $$.str[$$.len] = '\0';
472     }
473     ;
474 
475 /*
476  * A string that can contain dots.
477  */
478 dotted_str:	STR
479     |	'.'
480     {
481 	$$.str = ".";
482 	$$.len = 1;
483     }
484     |	dotted_str '.'
485     {
486 	    char *result = (char *) region_alloc(parser->rr_region,
487 						 $1.len + 2);
488 	    memcpy(result, $1.str, $1.len);
489 	    result[$1.len] = '.';
490 	    $$.str = result;
491 	    $$.len = $1.len + 1;
492 	    $$.str[$$.len] = '\0';
493     }
494     |	dotted_str '.' STR
495     {
496 	    char *result = (char *) region_alloc(parser->rr_region,
497 						 $1.len + $3.len + 2);
498 	    memcpy(result, $1.str, $1.len);
499 	    result[$1.len] = '.';
500 	    memcpy(result + $1.len + 1, $3.str, $3.len);
501 	    $$.str = result;
502 	    $$.len = $1.len + $3.len + 1;
503 	    $$.str[$$.len] = '\0';
504     }
505     ;
506 
507 /* define what we can parse */
508 type_and_rdata:
509     /*
510      * All supported RR types.	We don't support NULL and types marked obsolete.
511      */
512     	T_A sp rdata_a
513     |	T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
514     |	T_NS sp rdata_domain_name
515     |	T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
516     |	T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); }
517     |	T_MD sp rdata_unknown
518     {
519 	    zc_warning_prev_line("MD is obsolete");
520 	    $$ = $1; parse_unknown_rdata($1, $3);
521     }
522     |	T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); }
523     |	T_MF sp rdata_unknown
524     {
525 	    zc_warning_prev_line("MF is obsolete");
526 	    $$ = $1;
527 	    parse_unknown_rdata($1, $3);
528     }
529     |	T_CNAME sp rdata_domain_name
530     |	T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
531     |	T_SOA sp rdata_soa
532     |	T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
533     |	T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); }
534     |	T_MB sp rdata_unknown
535     {
536 	    zc_warning_prev_line("MB is obsolete");
537 	    $$ = $1;
538 	    parse_unknown_rdata($1, $3);
539     }
540     |	T_MG sp rdata_domain_name
541     |	T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
542     |	T_MR sp rdata_domain_name
543     |	T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
544       /* NULL */
545     |	T_WKS sp rdata_wks
546     |	T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
547     |	T_PTR sp rdata_domain_name
548     |	T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
549     |	T_HINFO sp rdata_hinfo
550     |	T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
551     |	T_MINFO sp rdata_minfo /* Experimental */
552     |	T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
553     |	T_MX sp rdata_mx
554     |	T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
555     |	T_TXT sp rdata_txt
556     |	T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
557     |	T_SPF sp rdata_txt
558     |	T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
559     |	T_RP sp rdata_rp		/* RFC 1183 */
560     |	T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
561     |	T_AFSDB sp rdata_afsdb	/* RFC 1183 */
562     |	T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
563     |	T_X25 sp rdata_x25	/* RFC 1183 */
564     |	T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
565     |	T_ISDN sp rdata_isdn	/* RFC 1183 */
566     |	T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
567     |	T_IPSECKEY sp rdata_ipseckey	/* RFC 4025 */
568     |	T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
569     |	T_DHCID sp rdata_dhcid
570     |	T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
571     |	T_RT sp rdata_rt		/* RFC 1183 */
572     |	T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
573     |	T_NSAP sp rdata_nsap	/* RFC 1706 */
574     |	T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
575     |	T_SIG sp rdata_rrsig
576     |	T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
577     |	T_KEY sp rdata_dnskey
578     |	T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
579     |	T_PX sp rdata_px		/* RFC 2163 */
580     |	T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
581     |	T_AAAA sp rdata_aaaa
582     |	T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
583     |	T_LOC sp rdata_loc
584     |	T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
585     |	T_NXT sp rdata_nxt
586     |	T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
587     |	T_SRV sp rdata_srv
588     |	T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
589     |	T_NAPTR sp rdata_naptr	/* RFC 2915 */
590     |	T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
591     |	T_KX sp rdata_kx		/* RFC 2230 */
592     |	T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
593     |	T_CERT sp rdata_cert	/* RFC 2538 */
594     |	T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
595     |	T_DNAME sp rdata_domain_name /* RFC 2672 */
596     |	T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
597     |	T_APL trail		/* RFC 3123 */
598     |	T_APL sp rdata_apl	/* RFC 3123 */
599     |	T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
600     |	T_DS sp rdata_ds
601     |	T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
602     |	T_DLV sp rdata_dlv { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } }
603     |	T_DLV sp rdata_unknown { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } $$ = $1; parse_unknown_rdata($1, $3); }
604     |	T_SSHFP sp rdata_sshfp
605     |	T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
606     |	T_RRSIG sp rdata_rrsig
607     |	T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
608     |	T_NSEC sp rdata_nsec
609     |	T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
610     |	T_NSEC3 sp rdata_nsec3
611     |	T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
612     |	T_NSEC3PARAM sp rdata_nsec3_param
613     |	T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
614     |	T_DNSKEY sp rdata_dnskey
615     |	T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
616     |	T_TLSA sp rdata_tlsa
617     |	T_TLSA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
618     |	T_NID sp rdata_nid
619     |	T_NID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
620     |	T_L32 sp rdata_l32
621     |	T_L32 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
622     |	T_L64 sp rdata_l64
623     |	T_L64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
624     |	T_LP sp rdata_lp
625     |	T_LP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
626     |	T_EUI48 sp rdata_eui48
627     |	T_EUI48 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
628     |	T_EUI64 sp rdata_eui64
629     |	T_EUI64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
630     |	T_CAA sp rdata_caa
631     |	T_CAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
632     |	T_CDS sp rdata_ds
633     |	T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
634     |	T_CDNSKEY sp rdata_dnskey
635     |	T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
636     |	T_CSYNC sp rdata_csync
637     |	T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
638     |	T_URI sp rdata_uri
639     |	T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
640     |	T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
641     |	STR error NL
642     {
643 	    zc_error_prev_line("unrecognized RR type '%s'", $1.str);
644     }
645     ;
646 
647 /*
648  *
649  * below are all the definition for all the different rdata
650  *
651  */
652 
653 rdata_a:	dotted_str trail
654     {
655 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str));
656     }
657     ;
658 
659 rdata_domain_name:	dname trail
660     {
661 	    /* convert a single dname record */
662 	    zadd_rdata_domain($1);
663     }
664     ;
665 
666 rdata_soa:	dname sp dname sp STR sp STR sp STR sp STR sp STR trail
667     {
668 	    /* convert the soa data */
669 	    zadd_rdata_domain($1);	/* prim. ns */
670 	    zadd_rdata_domain($3);	/* email */
671 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */
672 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */
673 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */
674 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */
675 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */
676     }
677     ;
678 
679 rdata_wks:	dotted_str sp STR sp concatenated_str_seq trail
680     {
681 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */
682 	    zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */
683     }
684     ;
685 
686 rdata_hinfo:	STR sp STR trail
687     {
688 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */
689 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/
690     }
691     ;
692 
693 rdata_minfo:	dname sp dname trail
694     {
695 	    /* convert a single dname record */
696 	    zadd_rdata_domain($1);
697 	    zadd_rdata_domain($3);
698     }
699     ;
700 
701 rdata_mx:	STR sp dname trail
702     {
703 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* priority */
704 	    zadd_rdata_domain($3);	/* MX host */
705     }
706     ;
707 
708 rdata_txt:	str_seq trail
709     {
710 	zadd_rdata_txt_clean_wireformat();
711     }
712     ;
713 
714 /* RFC 1183 */
715 rdata_rp:	dname sp dname trail
716     {
717 	    zadd_rdata_domain($1); /* mbox d-name */
718 	    zadd_rdata_domain($3); /* txt d-name */
719     }
720     ;
721 
722 /* RFC 1183 */
723 rdata_afsdb:	STR sp dname trail
724     {
725 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */
726 	    zadd_rdata_domain($3); /* domain name */
727     }
728     ;
729 
730 /* RFC 1183 */
731 rdata_x25:	STR trail
732     {
733 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */
734     }
735     ;
736 
737 /* RFC 1183 */
738 rdata_isdn:	STR trail
739     {
740 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
741     }
742     |	STR sp STR trail
743     {
744 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
745 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */
746     }
747     ;
748 
749 /* RFC 1183 */
750 rdata_rt:	STR sp dname trail
751     {
752 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
753 	    zadd_rdata_domain($3); /* intermediate host */
754     }
755     ;
756 
757 /* RFC 1706 */
758 rdata_nsap:	str_dot_seq trail
759     {
760 	    /* String must start with "0x" or "0X".	 */
761 	    if (strncasecmp($1.str, "0x", 2) != 0) {
762 		    zc_error_prev_line("NSAP rdata must start with '0x'");
763 	    } else {
764 		    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */
765 	    }
766     }
767     ;
768 
769 /* RFC 2163 */
770 rdata_px:	STR sp dname sp dname trail
771     {
772 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
773 	    zadd_rdata_domain($3); /* MAP822 */
774 	    zadd_rdata_domain($5); /* MAPX400 */
775     }
776     ;
777 
778 rdata_aaaa:	dotted_str trail
779     {
780 	    zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str));  /* IPv6 address */
781     }
782     ;
783 
784 rdata_loc:	concatenated_str_seq trail
785     {
786 	    zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */
787     }
788     ;
789 
790 rdata_nxt:	dname sp nxt_seq trail
791     {
792 	    zadd_rdata_domain($1); /* nxt name */
793 	    zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */
794 	    memset(nxtbits, 0, sizeof(nxtbits));
795     }
796     ;
797 
798 rdata_srv:	STR sp STR sp STR sp dname trail
799     {
800 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */
801 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
802 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */
803 	    zadd_rdata_domain($7); /* target name */
804     }
805     ;
806 
807 /* RFC 2915 */
808 rdata_naptr:	STR sp STR sp STR sp STR sp STR sp dname trail
809     {
810 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */
811 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */
812 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */
813 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */
814 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */
815 	    zadd_rdata_domain($11); /* target name */
816     }
817     ;
818 
819 /* RFC 2230 */
820 rdata_kx:	STR sp dname trail
821     {
822 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
823 	    zadd_rdata_domain($3); /* exchanger */
824     }
825     ;
826 
827 /* RFC 2538 */
828 rdata_cert:	STR sp STR sp STR sp str_sp_seq trail
829     {
830 	    zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */
831 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */
832 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */
833 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */
834     }
835     ;
836 
837 /* RFC 3123 */
838 rdata_apl:	rdata_apl_seq trail
839     ;
840 
841 rdata_apl_seq:	dotted_str
842     {
843 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str));
844     }
845     |	rdata_apl_seq sp dotted_str
846     {
847 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str));
848     }
849     ;
850 
851 rdata_ds:	STR sp STR sp STR sp str_sp_seq trail
852     {
853 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
854 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
855 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
856 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
857     }
858     ;
859 
860 rdata_dlv:	STR sp STR sp STR sp str_sp_seq trail
861     {
862 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
863 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
864 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
865 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
866     }
867     ;
868 
869 rdata_sshfp:	STR sp STR sp str_sp_seq trail
870     {
871 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */
872 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */
873 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */
874     }
875     ;
876 
877 rdata_dhcid:	str_sp_seq trail
878     {
879 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */
880     }
881     ;
882 
883 rdata_rrsig:	STR sp STR sp STR sp STR sp STR sp STR sp STR sp wire_dname sp str_sp_seq trail
884     {
885 	    zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */
886 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
887 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */
888 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */
889 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */
890 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */
891 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */
892 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
893 				(const uint8_t*) $15.str,$15.len)); /* sig name */
894 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */
895     }
896     ;
897 
898 rdata_nsec:	wire_dname nsec_seq
899     {
900 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
901 				(const uint8_t*) $1.str, $1.len)); /* nsec name */
902 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
903 	    memset(nsecbits, 0, sizeof(nsecbits));
904             nsec_highest_rcode = 0;
905     }
906     ;
907 
908 rdata_nsec3:   STR sp STR sp STR sp STR sp STR nsec_seq
909     {
910 #ifdef NSEC3
911 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
912 
913 	    zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */
914 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
915 	    memset(nsecbits, 0, sizeof(nsecbits));
916 	    nsec_highest_rcode = 0;
917 #else
918 	    zc_error_prev_line("nsec3 not supported");
919 #endif /* NSEC3 */
920     }
921     ;
922 
923 rdata_nsec3_param:   STR sp STR sp STR sp STR trail
924     {
925 #ifdef NSEC3
926 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
927 #else
928 	    zc_error_prev_line("nsec3 not supported");
929 #endif /* NSEC3 */
930     }
931     ;
932 
933 rdata_tlsa:	STR sp STR sp STR sp str_sp_seq trail
934     {
935 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
936 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
937 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
938 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
939     }
940     ;
941 
942 rdata_dnskey:	STR sp STR sp STR sp str_sp_seq trail
943     {
944 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */
945 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */
946 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */
947 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */
948     }
949     ;
950 
951 rdata_ipsec_base: STR sp STR sp STR sp dotted_str
952     {
953 	    const dname_type* name = 0;
954 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */
955 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */
956 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */
957 	    switch(atoi($3.str)) {
958 		case IPSECKEY_NOGATEWAY:
959 			zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0));
960 			break;
961 		case IPSECKEY_IP4:
962 			zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str));
963 			break;
964 		case IPSECKEY_IP6:
965 			zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $7.str));
966 			break;
967 		case IPSECKEY_DNAME:
968 			/* convert and insert the dname */
969 			if(strlen($7.str) == 0)
970 				zc_error_prev_line("IPSECKEY must specify gateway name");
971 			if(!(name = dname_parse(parser->region, $7.str)))
972 				zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str);
973 			if($7.str[strlen($7.str)-1] != '.') {
974 				if(parser->origin == error_domain) {
975 		    			zc_error("cannot concatenate origin to domain name, because origin failed to parse");
976 					break;
977 				}
978 				name = dname_concatenate(parser->rr_region, name,
979 					domain_dname(parser->origin));
980 			}
981 			zadd_rdata_wireformat(alloc_rdata_init(parser->region,
982 				dname_name(name), name->name_size));
983 			break;
984 		default:
985 			zc_error_prev_line("unknown IPSECKEY gateway type");
986 	    }
987     }
988     ;
989 
990 rdata_ipseckey:	rdata_ipsec_base sp str_sp_seq trail
991     {
992 	   zadd_rdata_wireformat(zparser_conv_b64(parser->region, $3.str)); /* public key */
993     }
994     | rdata_ipsec_base trail
995     ;
996 
997 /* RFC 6742 */
998 rdata_nid:	STR sp dotted_str trail
999     {
1000 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1001 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* NodeID */
1002     }
1003     ;
1004 
1005 rdata_l32:	STR sp dotted_str trail
1006     {
1007 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1008 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str));  /* Locator32 */
1009     }
1010     ;
1011 
1012 rdata_l64:	STR sp dotted_str trail
1013     {
1014 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1015 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* Locator64 */
1016     }
1017     ;
1018 
1019 rdata_lp:	STR sp dname trail
1020     {
1021 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1022 	    zadd_rdata_domain($3);  /* FQDN */
1023     }
1024     ;
1025 
1026 rdata_eui48:	STR trail
1027     {
1028 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
1029     }
1030     ;
1031 
1032 rdata_eui64:	STR trail
1033     {
1034 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
1035     }
1036     ;
1037 
1038 /* RFC7553 */
1039 rdata_uri:	STR sp STR sp STR trail
1040     {
1041 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
1042 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
1043 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */
1044     }
1045     ;
1046 
1047 /* RFC 6844 */
1048 rdata_caa:	STR sp STR sp STR trail
1049     {
1050 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */
1051 	    zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */
1052 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */
1053     }
1054     ;
1055 
1056 /* RFC7477 */
1057 rdata_csync:	STR sp STR nsec_seq
1058     {
1059 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str));
1060 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str));
1061 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
1062 	    memset(nsecbits, 0, sizeof(nsecbits));
1063             nsec_highest_rcode = 0;
1064     }
1065     ;
1066 
1067 rdata_unknown:	URR sp STR sp str_sp_seq trail
1068     {
1069 	    /* $2 is the number of octets, currently ignored */
1070 	    $$ = zparser_conv_hex(parser->region, $5.str, $5.len);
1071 
1072     }
1073     |	URR sp STR trail
1074     {
1075 	    $$ = zparser_conv_hex(parser->region, "", 0);
1076     }
1077     |	URR error NL
1078     {
1079 	    $$ = zparser_conv_hex(parser->region, "", 0);
1080     }
1081     ;
1082 %%
1083 
1084 int
1085 yywrap(void)
1086 {
1087 	return 1;
1088 }
1089 
1090 /*
1091  * Create the parser.
1092  */
1093 zparser_type *
1094 zparser_create(region_type *region, region_type *rr_region, namedb_type *db)
1095 {
1096 	zparser_type *result;
1097 
1098 	result = (zparser_type *) region_alloc(region, sizeof(zparser_type));
1099 	result->region = region;
1100 	result->rr_region = rr_region;
1101 	result->db = db;
1102 
1103 	result->filename = NULL;
1104 	result->current_zone = NULL;
1105 	result->origin = NULL;
1106 	result->prev_dname = NULL;
1107 	result->default_apex = NULL;
1108 
1109 	result->temporary_rdatas = (rdata_atom_type *) region_alloc_array(
1110 		result->region, MAXRDATALEN, sizeof(rdata_atom_type));
1111 
1112 	return result;
1113 }
1114 
1115 /*
1116  * Initialize the parser for a new zone file.
1117  */
1118 void
1119 zparser_init(const char *filename, uint32_t ttl, uint16_t klass,
1120 	     const dname_type *origin)
1121 {
1122 	memset(nxtbits, 0, sizeof(nxtbits));
1123 	memset(nsecbits, 0, sizeof(nsecbits));
1124         nsec_highest_rcode = 0;
1125 
1126 	parser->default_ttl = ttl;
1127 	parser->default_class = klass;
1128 	parser->current_zone = NULL;
1129 	parser->origin = domain_table_insert(parser->db->domains, origin);
1130 	parser->prev_dname = parser->origin;
1131 	parser->default_apex = parser->origin;
1132 	parser->error_occurred = 0;
1133 	parser->errors = 0;
1134 	parser->line = 1;
1135 	parser->filename = filename;
1136 	parser->current_rr.rdata_count = 0;
1137 	parser->current_rr.rdatas = parser->temporary_rdatas;
1138 }
1139 
1140 void
1141 yyerror(const char *message)
1142 {
1143 	zc_error("%s", message);
1144 }
1145 
1146 static void
1147 error_va_list(unsigned line, const char *fmt, va_list args)
1148 {
1149 	if (parser->filename) {
1150 		char message[MAXSYSLOGMSGLEN];
1151 		vsnprintf(message, sizeof(message), fmt, args);
1152 		log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message);
1153 	}
1154 	else log_vmsg(LOG_ERR, fmt, args);
1155 
1156 	++parser->errors;
1157 	parser->error_occurred = 1;
1158 }
1159 
1160 /* the line counting sux, to say the least
1161  * with this grose hack we try do give sane
1162  * numbers back */
1163 void
1164 zc_error_prev_line(const char *fmt, ...)
1165 {
1166 	va_list args;
1167 	va_start(args, fmt);
1168 	error_va_list(parser->line - 1, fmt, args);
1169 	va_end(args);
1170 }
1171 
1172 void
1173 zc_error(const char *fmt, ...)
1174 {
1175 	/* send an error message to stderr */
1176 	va_list args;
1177 	va_start(args, fmt);
1178 	error_va_list(parser->line, fmt, args);
1179 	va_end(args);
1180 }
1181 
1182 static void
1183 warning_va_list(unsigned line, const char *fmt, va_list args)
1184 {
1185 	if (parser->filename) {
1186 		char m[MAXSYSLOGMSGLEN];
1187 		vsnprintf(m, sizeof(m), fmt, args);
1188 		log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m);
1189 	}
1190 	else log_vmsg(LOG_WARNING, fmt, args);
1191 }
1192 
1193 void
1194 zc_warning_prev_line(const char *fmt, ...)
1195 {
1196 	va_list args;
1197 	va_start(args, fmt);
1198 	warning_va_list(parser->line - 1, fmt, args);
1199 	va_end(args);
1200 }
1201 
1202 void
1203 zc_warning(const char *fmt, ... )
1204 {
1205 	va_list args;
1206 	va_start(args, fmt);
1207 	warning_va_list(parser->line, fmt, args);
1208 	va_end(args);
1209 }
1210 
1211 #ifdef NSEC3
1212 static void
1213 nsec3_add_params(const char* hashalgo_str, const char* flag_str,
1214 	const char* iter_str, const char* salt_str, int salt_len)
1215 {
1216 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, hashalgo_str));
1217 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str));
1218 	zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str));
1219 
1220 	/* salt */
1221 	if(strcmp(salt_str, "-") != 0)
1222 		zadd_rdata_wireformat(zparser_conv_hex_length(parser->region,
1223 			salt_str, salt_len));
1224 	else
1225 		zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1));
1226 }
1227 #endif /* NSEC3 */
1228