xref: /netbsd/external/bsd/nsd/dist/zparser.y (revision 66a1527d)
1688d4060Schristos %{
2688d4060Schristos /*
3688d4060Schristos  * zyparser.y -- yacc grammar for (DNS) zone files
4688d4060Schristos  *
5688d4060Schristos  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
6688d4060Schristos  *
7688d4060Schristos  * See LICENSE for the license.
8688d4060Schristos  *
9688d4060Schristos  */
10688d4060Schristos 
11688d4060Schristos #include "config.h"
12688d4060Schristos 
13688d4060Schristos #include <stdarg.h>
14688d4060Schristos #include <stdio.h>
15688d4060Schristos #include <string.h>
16688d4060Schristos 
17688d4060Schristos #include "dname.h"
18688d4060Schristos #include "namedb.h"
19688d4060Schristos #include "zonec.h"
20688d4060Schristos 
21688d4060Schristos /* these need to be global, otherwise they cannot be used inside yacc */
22688d4060Schristos zparser_type *parser;
23688d4060Schristos 
24688d4060Schristos #ifdef __cplusplus
25688d4060Schristos extern "C"
26688d4060Schristos #endif /* __cplusplus */
27688d4060Schristos int yywrap(void);
28688d4060Schristos 
29688d4060Schristos /* this hold the nxt bits */
30688d4060Schristos static uint8_t nxtbits[16];
31688d4060Schristos static int dlv_warn = 1;
32688d4060Schristos 
33688d4060Schristos /* 256 windows of 256 bits (32 bytes) */
34688d4060Schristos /* still need to reset the bastard somewhere */
35688d4060Schristos static uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
36688d4060Schristos 
37688d4060Schristos /* hold the highest rcode seen in a NSEC rdata , BUG #106 */
38688d4060Schristos uint16_t nsec_highest_rcode;
39688d4060Schristos 
40688d4060Schristos void yyerror(const char *message);
41688d4060Schristos 
42688d4060Schristos #ifdef NSEC3
43688d4060Schristos /* parse nsec3 parameters and add the (first) rdata elements */
44688d4060Schristos static void
45688d4060Schristos nsec3_add_params(const char* hash_algo_str, const char* flag_str,
46688d4060Schristos 	const char* iter_str, const char* salt_str, int salt_len);
47688d4060Schristos #endif /* NSEC3 */
48688d4060Schristos 
49688d4060Schristos %}
50688d4060Schristos %union {
51688d4060Schristos 	domain_type	 *domain;
52688d4060Schristos 	const dname_type *dname;
53688d4060Schristos 	struct lex_data	  data;
54688d4060Schristos 	uint32_t	  ttl;
55688d4060Schristos 	uint16_t	  klass;
56688d4060Schristos 	uint16_t	  type;
57688d4060Schristos 	uint16_t	 *unknown;
58688d4060Schristos }
59688d4060Schristos 
60688d4060Schristos /*
61688d4060Schristos  * Tokens to represent the known RR types of DNS.
62688d4060Schristos  */
63688d4060Schristos %token <type> T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG
64688d4060Schristos %token <type> T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO
65688d4060Schristos %token <type> T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX
66688d4060Schristos %token <type> T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK
67688d4060Schristos %token <type> T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR
68688d4060Schristos %token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY
69688d4060Schristos %token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI
70688d4060Schristos %token <type> T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY
71*66a1527dSchristos %token <type> T_OPENPGPKEY T_CSYNC T_ZONEMD T_AVC T_SMIMEA T_SVCB T_HTTPS
72688d4060Schristos 
73688d4060Schristos /* other tokens */
74688d4060Schristos %token	       DOLLAR_TTL DOLLAR_ORIGIN NL SP
75*66a1527dSchristos %token <data>  QSTR STR PREV BITLAB
76688d4060Schristos %token <ttl>   T_TTL
77688d4060Schristos %token <klass> T_RRCLASS
78688d4060Schristos 
79688d4060Schristos /* unknown RRs */
80688d4060Schristos %token	       URR
81688d4060Schristos %token <type>  T_UTYPE
82688d4060Schristos 
83688d4060Schristos %type <type>	type_and_rdata
84688d4060Schristos %type <domain>	owner dname abs_dname
85688d4060Schristos %type <dname>	rel_dname label
86688d4060Schristos %type <data>	wire_dname wire_abs_dname wire_rel_dname wire_label
87*66a1527dSchristos %type <data>	str concatenated_str_seq str_sp_seq str_dot_seq
88*66a1527dSchristos %type <data>	unquoted_dotted_str dotted_str svcparam svcparams
89688d4060Schristos %type <data>	nxt_seq nsec_more
90688d4060Schristos %type <unknown> rdata_unknown
91688d4060Schristos 
92688d4060Schristos %%
93688d4060Schristos lines:	/* empty file */
94688d4060Schristos     |	lines line
95688d4060Schristos     ;
96688d4060Schristos 
97688d4060Schristos line:	NL
98688d4060Schristos     |	sp NL
99688d4060Schristos     |	PREV NL		{}    /* Lines containing only whitespace.  */
100688d4060Schristos     |	ttl_directive
101688d4060Schristos 	{
102688d4060Schristos 	    region_free_all(parser->rr_region);
103688d4060Schristos 	    parser->current_rr.type = 0;
104688d4060Schristos 	    parser->current_rr.rdata_count = 0;
105688d4060Schristos 	    parser->current_rr.rdatas = parser->temporary_rdatas;
106688d4060Schristos 	    parser->error_occurred = 0;
107688d4060Schristos     }
108688d4060Schristos     |	origin_directive
109688d4060Schristos 	{
110688d4060Schristos 	    region_free_all(parser->rr_region);
111688d4060Schristos 	    parser->current_rr.type = 0;
112688d4060Schristos 	    parser->current_rr.rdata_count = 0;
113688d4060Schristos 	    parser->current_rr.rdatas = parser->temporary_rdatas;
114688d4060Schristos 	    parser->error_occurred = 0;
115688d4060Schristos     }
116688d4060Schristos     |	rr
117688d4060Schristos     {	/* rr should be fully parsed */
118688d4060Schristos 	    if (!parser->error_occurred) {
119688d4060Schristos 			    parser->current_rr.rdatas
120688d4060Schristos 				    =(rdata_atom_type *)region_alloc_array_init(
121688d4060Schristos 					    parser->region,
122688d4060Schristos 					    parser->current_rr.rdatas,
123688d4060Schristos 					    parser->current_rr.rdata_count,
124688d4060Schristos 					    sizeof(rdata_atom_type));
125688d4060Schristos 
126688d4060Schristos 			    process_rr();
127688d4060Schristos 	    }
128688d4060Schristos 
129688d4060Schristos 	    region_free_all(parser->rr_region);
130688d4060Schristos 
131688d4060Schristos 	    parser->current_rr.type = 0;
132688d4060Schristos 	    parser->current_rr.rdata_count = 0;
133688d4060Schristos 	    parser->current_rr.rdatas = parser->temporary_rdatas;
134688d4060Schristos 	    parser->error_occurred = 0;
135688d4060Schristos     }
136688d4060Schristos     |	error NL
137688d4060Schristos     ;
138688d4060Schristos 
139688d4060Schristos /* needed to cope with ( and ) in arbitrary places */
140688d4060Schristos sp:	SP
141688d4060Schristos     |	sp SP
142688d4060Schristos     ;
143688d4060Schristos 
144*66a1527dSchristos str:	STR | QSTR;
145*66a1527dSchristos 
146688d4060Schristos trail:	NL
147688d4060Schristos     |	sp NL
148688d4060Schristos     ;
149688d4060Schristos 
150*66a1527dSchristos ttl_directive:	DOLLAR_TTL sp str trail
151688d4060Schristos     {
152688d4060Schristos 	    parser->default_ttl = zparser_ttl2int($3.str, &(parser->error_occurred));
153688d4060Schristos 	    if (parser->error_occurred == 1) {
154688d4060Schristos 		    parser->default_ttl = DEFAULT_TTL;
155688d4060Schristos 			parser->error_occurred = 0;
156688d4060Schristos 	    }
157688d4060Schristos     }
158688d4060Schristos     ;
159688d4060Schristos 
160688d4060Schristos origin_directive:	DOLLAR_ORIGIN sp abs_dname trail
161688d4060Schristos     {
162688d4060Schristos 	    /* if previous origin is unused, remove it, do not leak it */
163688d4060Schristos 	    if(parser->origin != error_domain && parser->origin != $3) {
164688d4060Schristos 		/* protect $3 from deletion, because deldomain walks up */
165688d4060Schristos 		$3->usage ++;
166688d4060Schristos 	    	domain_table_deldomain(parser->db, parser->origin);
167688d4060Schristos 		$3->usage --;
168688d4060Schristos 	    }
169688d4060Schristos 	    parser->origin = $3;
170688d4060Schristos     }
171688d4060Schristos     |	DOLLAR_ORIGIN sp rel_dname trail
172688d4060Schristos     {
173688d4060Schristos 	    zc_error_prev_line("$ORIGIN directive requires absolute domain name");
174688d4060Schristos     }
175688d4060Schristos     ;
176688d4060Schristos 
177688d4060Schristos rr:	owner classttl type_and_rdata
178688d4060Schristos     {
179688d4060Schristos 	    parser->current_rr.owner = $1;
180688d4060Schristos 	    parser->current_rr.type = $3;
181688d4060Schristos     }
182688d4060Schristos     ;
183688d4060Schristos 
184688d4060Schristos owner:	dname sp
185688d4060Schristos     {
186688d4060Schristos 	    parser->prev_dname = $1;
187688d4060Schristos 	    $$ = $1;
188688d4060Schristos     }
189688d4060Schristos     |	PREV
190688d4060Schristos     {
191688d4060Schristos 	    $$ = parser->prev_dname;
192688d4060Schristos     }
193688d4060Schristos     ;
194688d4060Schristos 
195688d4060Schristos classttl:	/* empty - fill in the default, def. ttl and IN class */
196688d4060Schristos     {
197688d4060Schristos 	    parser->current_rr.ttl = parser->default_ttl;
198688d4060Schristos 	    parser->current_rr.klass = parser->default_class;
199688d4060Schristos     }
200688d4060Schristos     |	T_RRCLASS sp		/* no ttl */
201688d4060Schristos     {
202688d4060Schristos 	    parser->current_rr.ttl = parser->default_ttl;
203688d4060Schristos 	    parser->current_rr.klass = $1;
204688d4060Schristos     }
205688d4060Schristos     |	T_TTL sp		/* no class */
206688d4060Schristos     {
207688d4060Schristos 	    parser->current_rr.ttl = $1;
208688d4060Schristos 	    parser->current_rr.klass = parser->default_class;
209688d4060Schristos     }
210688d4060Schristos     |	T_TTL sp T_RRCLASS sp	/* the lot */
211688d4060Schristos     {
212688d4060Schristos 	    parser->current_rr.ttl = $1;
213688d4060Schristos 	    parser->current_rr.klass = $3;
214688d4060Schristos     }
215688d4060Schristos     |	T_RRCLASS sp T_TTL sp	/* the lot - reversed */
216688d4060Schristos     {
217688d4060Schristos 	    parser->current_rr.ttl = $3;
218688d4060Schristos 	    parser->current_rr.klass = $1;
219688d4060Schristos     }
220688d4060Schristos     ;
221688d4060Schristos 
222688d4060Schristos dname:	abs_dname
223688d4060Schristos     |	rel_dname
224688d4060Schristos     {
225688d4060Schristos 	    if ($1 == error_dname) {
226688d4060Schristos 		    $$ = error_domain;
227688d4060Schristos 	    } else if(parser->origin == error_domain) {
228688d4060Schristos 		    zc_error("cannot concatenate origin to domain name, because origin failed to parse");
229688d4060Schristos 		    $$ = error_domain;
230688d4060Schristos 	    } else if ($1->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) {
231688d4060Schristos 		    zc_error("domain name exceeds %d character limit", MAXDOMAINLEN);
232688d4060Schristos 		    $$ = error_domain;
233688d4060Schristos 	    } else {
234688d4060Schristos 		    $$ = domain_table_insert(
235688d4060Schristos 			    parser->db->domains,
236688d4060Schristos 			    dname_concatenate(
237688d4060Schristos 				    parser->rr_region,
238688d4060Schristos 				    $1,
239688d4060Schristos 				    domain_dname(parser->origin)));
240688d4060Schristos 	    }
241688d4060Schristos     }
242688d4060Schristos     ;
243688d4060Schristos 
244688d4060Schristos abs_dname:	'.'
245688d4060Schristos     {
246688d4060Schristos 	    $$ = parser->db->domains->root;
247688d4060Schristos     }
248688d4060Schristos     |	'@'
249688d4060Schristos     {
250688d4060Schristos 	    $$ = parser->origin;
251688d4060Schristos     }
252688d4060Schristos     |	rel_dname '.'
253688d4060Schristos     {
254688d4060Schristos 	    if ($1 != error_dname) {
255688d4060Schristos 		    $$ = domain_table_insert(parser->db->domains, $1);
256688d4060Schristos 	    } else {
257688d4060Schristos 		    $$ = error_domain;
258688d4060Schristos 	    }
259688d4060Schristos     }
260688d4060Schristos     ;
261688d4060Schristos 
262*66a1527dSchristos label:	str
263688d4060Schristos     {
264688d4060Schristos 	    if ($1.len > MAXLABELLEN) {
265688d4060Schristos 		    zc_error("label exceeds %d character limit", MAXLABELLEN);
266688d4060Schristos 		    $$ = error_dname;
267688d4060Schristos 	    } else if ($1.len <= 0) {
268688d4060Schristos 		    zc_error("zero label length");
269688d4060Schristos 		    $$ = error_dname;
270688d4060Schristos 	    } else {
271688d4060Schristos 		    $$ = dname_make_from_label(parser->rr_region,
272688d4060Schristos 					       (uint8_t *) $1.str,
273688d4060Schristos 					       $1.len);
274688d4060Schristos 	    }
275688d4060Schristos     }
276688d4060Schristos     |	BITLAB
277688d4060Schristos     {
278688d4060Schristos 	    zc_error("bitlabels are now deprecated. RFC2673 is obsoleted.");
279688d4060Schristos 	    $$ = error_dname;
280688d4060Schristos     }
281688d4060Schristos     ;
282688d4060Schristos 
283688d4060Schristos rel_dname:	label
284688d4060Schristos     |	rel_dname '.' label
285688d4060Schristos     {
286688d4060Schristos 	    if ($1 == error_dname || $3 == error_dname) {
287688d4060Schristos 		    $$ = error_dname;
288688d4060Schristos 	    } else if ($1->name_size + $3->name_size - 1 > MAXDOMAINLEN) {
289688d4060Schristos 		    zc_error("domain name exceeds %d character limit",
290688d4060Schristos 			     MAXDOMAINLEN);
291688d4060Schristos 		    $$ = error_dname;
292688d4060Schristos 	    } else {
293688d4060Schristos 		    $$ = dname_concatenate(parser->rr_region, $1, $3);
294688d4060Schristos 	    }
295688d4060Schristos     }
296688d4060Schristos     ;
297688d4060Schristos 
298688d4060Schristos /*
299688d4060Schristos  * Some dnames in rdata are handled as opaque blobs
300688d4060Schristos  */
301688d4060Schristos 
302688d4060Schristos wire_dname:	wire_abs_dname
303688d4060Schristos     |	wire_rel_dname
304cd92f1a1Sprlw1     {
305cd92f1a1Sprlw1 	    /* terminate in root label and copy the origin in there */
306cd92f1a1Sprlw1 	    if(parser->origin && domain_dname(parser->origin)) {
307cd92f1a1Sprlw1 		    $$.len = $1.len + domain_dname(parser->origin)->name_size;
308cd92f1a1Sprlw1 		    if ($$.len > MAXDOMAINLEN)
309cd92f1a1Sprlw1 			    zc_error("domain name exceeds %d character limit",
310cd92f1a1Sprlw1 				     MAXDOMAINLEN);
311cd92f1a1Sprlw1 		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
312cd92f1a1Sprlw1 		    memmove($$.str, $1.str, $1.len);
313cd92f1a1Sprlw1 		    memmove($$.str + $1.len, dname_name(domain_dname(parser->origin)),
314cd92f1a1Sprlw1 			domain_dname(parser->origin)->name_size);
315cd92f1a1Sprlw1 	    } else {
316cd92f1a1Sprlw1 		    $$.len = $1.len + 1;
317cd92f1a1Sprlw1 		    if ($$.len > MAXDOMAINLEN)
318cd92f1a1Sprlw1 			    zc_error("domain name exceeds %d character limit",
319cd92f1a1Sprlw1 				     MAXDOMAINLEN);
320cd92f1a1Sprlw1 		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
321cd92f1a1Sprlw1 		    memmove($$.str, $1.str, $1.len);
322cd92f1a1Sprlw1 		    $$.str[ $1.len ] = 0;
323cd92f1a1Sprlw1 	    }
324cd92f1a1Sprlw1     }
325688d4060Schristos     ;
326688d4060Schristos 
327688d4060Schristos wire_abs_dname:	'.'
328688d4060Schristos     {
329cd92f1a1Sprlw1 	    char *result = (char *) region_alloc(parser->rr_region, 1);
330688d4060Schristos 	    result[0] = 0;
331688d4060Schristos 	    $$.str = result;
332688d4060Schristos 	    $$.len = 1;
333688d4060Schristos     }
334cd92f1a1Sprlw1     |	'@'
335cd92f1a1Sprlw1     {
336cd92f1a1Sprlw1 	    if(parser->origin && domain_dname(parser->origin)) {
337cd92f1a1Sprlw1 		    $$.len = domain_dname(parser->origin)->name_size;
338cd92f1a1Sprlw1 		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
339cd92f1a1Sprlw1 		    memmove($$.str, dname_name(domain_dname(parser->origin)), $$.len);
340cd92f1a1Sprlw1 	    } else {
341cd92f1a1Sprlw1 		    $$.len = 1;
342cd92f1a1Sprlw1 		    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
343cd92f1a1Sprlw1 		    $$.str[0] = 0;
344cd92f1a1Sprlw1 	    }
345cd92f1a1Sprlw1     }
346688d4060Schristos     |	wire_rel_dname '.'
347688d4060Schristos     {
348688d4060Schristos 	    $$.len = $1.len + 1;
349cd92f1a1Sprlw1 	    if ($$.len > MAXDOMAINLEN)
350cd92f1a1Sprlw1 		    zc_error("domain name exceeds %d character limit",
351cd92f1a1Sprlw1 			     MAXDOMAINLEN);
352cd92f1a1Sprlw1 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
353cd92f1a1Sprlw1 	    memcpy($$.str, $1.str, $1.len);
354cd92f1a1Sprlw1 	    $$.str[$1.len] = 0;
355688d4060Schristos     }
356688d4060Schristos     ;
357688d4060Schristos 
358*66a1527dSchristos wire_label:	str
359688d4060Schristos     {
360688d4060Schristos 	    char *result = (char *) region_alloc(parser->rr_region,
361688d4060Schristos 						 $1.len + 1);
362688d4060Schristos 
363688d4060Schristos 	    if ($1.len > MAXLABELLEN)
364688d4060Schristos 		    zc_error("label exceeds %d character limit", MAXLABELLEN);
365688d4060Schristos 
366688d4060Schristos 	    /* make label anyway */
367688d4060Schristos 	    result[0] = $1.len;
368cd92f1a1Sprlw1 	    memmove(result+1, $1.str, $1.len);
369688d4060Schristos 
370688d4060Schristos 	    $$.str = result;
371688d4060Schristos 	    $$.len = $1.len + 1;
372688d4060Schristos     }
373688d4060Schristos     ;
374688d4060Schristos 
375688d4060Schristos wire_rel_dname:	wire_label
376688d4060Schristos     |	wire_rel_dname '.' wire_label
377688d4060Schristos     {
378cd92f1a1Sprlw1 	    $$.len = $1.len + $3.len;
379cd92f1a1Sprlw1 	    if ($$.len > MAXDOMAINLEN)
380688d4060Schristos 		    zc_error("domain name exceeds %d character limit",
381688d4060Schristos 			     MAXDOMAINLEN);
382cd92f1a1Sprlw1 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len);
383cd92f1a1Sprlw1 	    memmove($$.str, $1.str, $1.len);
384cd92f1a1Sprlw1 	    memmove($$.str + $1.len, $3.str, $3.len);
385688d4060Schristos     }
386688d4060Schristos     ;
387688d4060Schristos 
388*66a1527dSchristos str_seq:	unquoted_dotted_str
389688d4060Schristos     {
390688d4060Schristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
391688d4060Schristos     }
392*66a1527dSchristos     |	QSTR
393*66a1527dSchristos     {
394*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
395*66a1527dSchristos     }
396*66a1527dSchristos     |	QSTR unquoted_dotted_str
397*66a1527dSchristos     {
398*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1);
399*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
400*66a1527dSchristos     }
401*66a1527dSchristos     |	str_seq QSTR
402*66a1527dSchristos     {
403*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
404*66a1527dSchristos     }
405*66a1527dSchristos     |	str_seq QSTR unquoted_dotted_str
406*66a1527dSchristos     {
407*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0);
408*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
409*66a1527dSchristos     }
410*66a1527dSchristos     |	str_seq sp unquoted_dotted_str
411688d4060Schristos     {
412688d4060Schristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
413688d4060Schristos     }
414*66a1527dSchristos     |	str_seq sp QSTR
415*66a1527dSchristos     {
416*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
417*66a1527dSchristos     }
418*66a1527dSchristos     |	str_seq sp QSTR unquoted_dotted_str
419*66a1527dSchristos     {
420*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0);
421*66a1527dSchristos 	    zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $4.str, $4.len), 0);
422*66a1527dSchristos     }
423688d4060Schristos     ;
424688d4060Schristos 
425688d4060Schristos /*
426688d4060Schristos  * Generate a single string from multiple STR tokens, separated by
427688d4060Schristos  * spaces or dots.
428688d4060Schristos  */
429*66a1527dSchristos concatenated_str_seq:	str
430688d4060Schristos     |	'.'
431688d4060Schristos     {
432688d4060Schristos 	    $$.len = 1;
433688d4060Schristos 	    $$.str = region_strdup(parser->rr_region, ".");
434688d4060Schristos     }
435*66a1527dSchristos     |	concatenated_str_seq sp str
436688d4060Schristos     {
437688d4060Schristos 	    $$.len = $1.len + $3.len + 1;
438688d4060Schristos 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
439688d4060Schristos 	    memcpy($$.str, $1.str, $1.len);
440688d4060Schristos 	    memcpy($$.str + $1.len, " ", 1);
441688d4060Schristos 	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
442688d4060Schristos 	    $$.str[$$.len] = '\0';
443688d4060Schristos     }
444*66a1527dSchristos     |	concatenated_str_seq '.' str
445688d4060Schristos     {
446688d4060Schristos 	    $$.len = $1.len + $3.len + 1;
447688d4060Schristos 	    $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1);
448688d4060Schristos 	    memcpy($$.str, $1.str, $1.len);
449688d4060Schristos 	    memcpy($$.str + $1.len, ".", 1);
450688d4060Schristos 	    memcpy($$.str + $1.len + 1, $3.str, $3.len);
451688d4060Schristos 	    $$.str[$$.len] = '\0';
452688d4060Schristos     }
453688d4060Schristos     ;
454688d4060Schristos 
455688d4060Schristos /* used to convert a nxt list of types */
456*66a1527dSchristos nxt_seq:	str
457688d4060Schristos     {
458688d4060Schristos 	    uint16_t type = rrtype_from_string($1.str);
459688d4060Schristos 	    if (type != 0 && type < 128) {
460688d4060Schristos 		    set_bit(nxtbits, type);
461688d4060Schristos 	    } else {
462688d4060Schristos 		    zc_error("bad type %d in NXT record", (int) type);
463688d4060Schristos 	    }
464688d4060Schristos     }
465*66a1527dSchristos     |	nxt_seq sp str
466688d4060Schristos     {
467688d4060Schristos 	    uint16_t type = rrtype_from_string($3.str);
468688d4060Schristos 	    if (type != 0 && type < 128) {
469688d4060Schristos 		    set_bit(nxtbits, type);
470688d4060Schristos 	    } else {
471688d4060Schristos 		    zc_error("bad type %d in NXT record", (int) type);
472688d4060Schristos 	    }
473688d4060Schristos     }
474688d4060Schristos     ;
475688d4060Schristos 
476688d4060Schristos nsec_more:	SP nsec_more
477688d4060Schristos     {
478688d4060Schristos     }
479688d4060Schristos     |	NL
480688d4060Schristos     {
481688d4060Schristos     }
482*66a1527dSchristos     |	str nsec_seq
483688d4060Schristos     {
484688d4060Schristos 	    uint16_t type = rrtype_from_string($1.str);
485688d4060Schristos 	    if (type != 0) {
486688d4060Schristos                     if (type > nsec_highest_rcode) {
487688d4060Schristos                             nsec_highest_rcode = type;
488688d4060Schristos                     }
489688d4060Schristos 		    set_bitnsec(nsecbits, type);
490688d4060Schristos 	    } else {
491688d4060Schristos 		    zc_error("bad type %d in NSEC record", (int) type);
492688d4060Schristos 	    }
493688d4060Schristos     }
494688d4060Schristos     ;
495688d4060Schristos 
496688d4060Schristos nsec_seq:	NL
497688d4060Schristos 	|	SP nsec_more
498688d4060Schristos 	;
499688d4060Schristos 
500688d4060Schristos /*
501688d4060Schristos  * Sequence of STR tokens separated by spaces.	The spaces are not
502688d4060Schristos  * preserved during concatenation.
503688d4060Schristos  */
504*66a1527dSchristos str_sp_seq:	str
505*66a1527dSchristos     |	str_sp_seq sp str
506688d4060Schristos     {
507688d4060Schristos 	    char *result = (char *) region_alloc(parser->rr_region,
508688d4060Schristos 						 $1.len + $3.len + 1);
509688d4060Schristos 	    memcpy(result, $1.str, $1.len);
510688d4060Schristos 	    memcpy(result + $1.len, $3.str, $3.len);
511688d4060Schristos 	    $$.str = result;
512688d4060Schristos 	    $$.len = $1.len + $3.len;
513688d4060Schristos 	    $$.str[$$.len] = '\0';
514688d4060Schristos     }
515688d4060Schristos     ;
516688d4060Schristos 
517688d4060Schristos /*
518688d4060Schristos  * Sequence of STR tokens separated by dots.  The dots are not
519688d4060Schristos  * preserved during concatenation.
520688d4060Schristos  */
521*66a1527dSchristos str_dot_seq:	str
522*66a1527dSchristos     |	str_dot_seq '.' str
523688d4060Schristos     {
524688d4060Schristos 	    char *result = (char *) region_alloc(parser->rr_region,
525688d4060Schristos 						 $1.len + $3.len + 1);
526688d4060Schristos 	    memcpy(result, $1.str, $1.len);
527688d4060Schristos 	    memcpy(result + $1.len, $3.str, $3.len);
528688d4060Schristos 	    $$.str = result;
529688d4060Schristos 	    $$.len = $1.len + $3.len;
530688d4060Schristos 	    $$.str[$$.len] = '\0';
531688d4060Schristos     }
532688d4060Schristos     ;
533688d4060Schristos 
534688d4060Schristos /*
535688d4060Schristos  * A string that can contain dots.
536688d4060Schristos  */
537*66a1527dSchristos unquoted_dotted_str:	STR
538688d4060Schristos     |	'.'
539688d4060Schristos     {
540688d4060Schristos 	$$.str = ".";
541688d4060Schristos 	$$.len = 1;
542688d4060Schristos     }
543*66a1527dSchristos     |	unquoted_dotted_str '.'
544688d4060Schristos     {
545688d4060Schristos 	    char *result = (char *) region_alloc(parser->rr_region,
546688d4060Schristos 						 $1.len + 2);
547688d4060Schristos 	    memcpy(result, $1.str, $1.len);
548688d4060Schristos 	    result[$1.len] = '.';
549688d4060Schristos 	    $$.str = result;
550688d4060Schristos 	    $$.len = $1.len + 1;
551688d4060Schristos 	    $$.str[$$.len] = '\0';
552688d4060Schristos     }
553*66a1527dSchristos     |	unquoted_dotted_str '.' STR
554688d4060Schristos     {
555688d4060Schristos 	    char *result = (char *) region_alloc(parser->rr_region,
556688d4060Schristos 						 $1.len + $3.len + 2);
557688d4060Schristos 	    memcpy(result, $1.str, $1.len);
558688d4060Schristos 	    result[$1.len] = '.';
559688d4060Schristos 	    memcpy(result + $1.len + 1, $3.str, $3.len);
560688d4060Schristos 	    $$.str = result;
561688d4060Schristos 	    $$.len = $1.len + $3.len + 1;
562688d4060Schristos 	    $$.str[$$.len] = '\0';
563688d4060Schristos     }
564688d4060Schristos     ;
565688d4060Schristos 
566*66a1527dSchristos /*
567*66a1527dSchristos  * A string that can contain dots or a quoted string.
568*66a1527dSchristos  */
569*66a1527dSchristos dotted_str:	unquoted_dotted_str | QSTR
570*66a1527dSchristos 
571688d4060Schristos /* define what we can parse */
572688d4060Schristos type_and_rdata:
573688d4060Schristos     /*
574688d4060Schristos      * All supported RR types.	We don't support NULL and types marked obsolete.
575688d4060Schristos      */
576688d4060Schristos     	T_A sp rdata_a
577688d4060Schristos     |	T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
578688d4060Schristos     |	T_NS sp rdata_domain_name
579688d4060Schristos     |	T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
580688d4060Schristos     |	T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); }
581688d4060Schristos     |	T_MD sp rdata_unknown
582688d4060Schristos     {
583688d4060Schristos 	    zc_warning_prev_line("MD is obsolete");
584688d4060Schristos 	    $$ = $1; parse_unknown_rdata($1, $3);
585688d4060Schristos     }
586688d4060Schristos     |	T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); }
587688d4060Schristos     |	T_MF sp rdata_unknown
588688d4060Schristos     {
589688d4060Schristos 	    zc_warning_prev_line("MF is obsolete");
590688d4060Schristos 	    $$ = $1;
591688d4060Schristos 	    parse_unknown_rdata($1, $3);
592688d4060Schristos     }
593688d4060Schristos     |	T_CNAME sp rdata_domain_name
594688d4060Schristos     |	T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
595688d4060Schristos     |	T_SOA sp rdata_soa
596688d4060Schristos     |	T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
597688d4060Schristos     |	T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); }
598688d4060Schristos     |	T_MB sp rdata_unknown
599688d4060Schristos     {
600688d4060Schristos 	    zc_warning_prev_line("MB is obsolete");
601688d4060Schristos 	    $$ = $1;
602688d4060Schristos 	    parse_unknown_rdata($1, $3);
603688d4060Schristos     }
604688d4060Schristos     |	T_MG sp rdata_domain_name
605688d4060Schristos     |	T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
606688d4060Schristos     |	T_MR sp rdata_domain_name
607688d4060Schristos     |	T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
608688d4060Schristos       /* NULL */
609688d4060Schristos     |	T_WKS sp rdata_wks
610688d4060Schristos     |	T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
611688d4060Schristos     |	T_PTR sp rdata_domain_name
612688d4060Schristos     |	T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
613688d4060Schristos     |	T_HINFO sp rdata_hinfo
614688d4060Schristos     |	T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
615688d4060Schristos     |	T_MINFO sp rdata_minfo /* Experimental */
616688d4060Schristos     |	T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
617688d4060Schristos     |	T_MX sp rdata_mx
618688d4060Schristos     |	T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
619688d4060Schristos     |	T_TXT sp rdata_txt
620688d4060Schristos     |	T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
621688d4060Schristos     |	T_SPF sp rdata_txt
622688d4060Schristos     |	T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
623df8774c2Schristos     |	T_AVC sp rdata_txt
624df8774c2Schristos     |	T_AVC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
625688d4060Schristos     |	T_RP sp rdata_rp		/* RFC 1183 */
626688d4060Schristos     |	T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
627688d4060Schristos     |	T_AFSDB sp rdata_afsdb	/* RFC 1183 */
628688d4060Schristos     |	T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
629688d4060Schristos     |	T_X25 sp rdata_x25	/* RFC 1183 */
630688d4060Schristos     |	T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
631688d4060Schristos     |	T_ISDN sp rdata_isdn	/* RFC 1183 */
632688d4060Schristos     |	T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
633688d4060Schristos     |	T_IPSECKEY sp rdata_ipseckey	/* RFC 4025 */
634688d4060Schristos     |	T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
635688d4060Schristos     |	T_DHCID sp rdata_dhcid
636688d4060Schristos     |	T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
637688d4060Schristos     |	T_RT sp rdata_rt		/* RFC 1183 */
638688d4060Schristos     |	T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
639688d4060Schristos     |	T_NSAP sp rdata_nsap	/* RFC 1706 */
640688d4060Schristos     |	T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
641688d4060Schristos     |	T_SIG sp rdata_rrsig
642688d4060Schristos     |	T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
643688d4060Schristos     |	T_KEY sp rdata_dnskey
644688d4060Schristos     |	T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
645688d4060Schristos     |	T_PX sp rdata_px		/* RFC 2163 */
646688d4060Schristos     |	T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
647688d4060Schristos     |	T_AAAA sp rdata_aaaa
648688d4060Schristos     |	T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
649688d4060Schristos     |	T_LOC sp rdata_loc
650688d4060Schristos     |	T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
651688d4060Schristos     |	T_NXT sp rdata_nxt
652688d4060Schristos     |	T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
653688d4060Schristos     |	T_SRV sp rdata_srv
654688d4060Schristos     |	T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
655688d4060Schristos     |	T_NAPTR sp rdata_naptr	/* RFC 2915 */
656688d4060Schristos     |	T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
657688d4060Schristos     |	T_KX sp rdata_kx		/* RFC 2230 */
658688d4060Schristos     |	T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
659688d4060Schristos     |	T_CERT sp rdata_cert	/* RFC 2538 */
660688d4060Schristos     |	T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
661688d4060Schristos     |	T_DNAME sp rdata_domain_name /* RFC 2672 */
662688d4060Schristos     |	T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
663688d4060Schristos     |	T_APL trail		/* RFC 3123 */
664688d4060Schristos     |	T_APL sp rdata_apl	/* RFC 3123 */
665688d4060Schristos     |	T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
666688d4060Schristos     |	T_DS sp rdata_ds
667688d4060Schristos     |	T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
668688d4060Schristos     |	T_DLV sp rdata_dlv { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } }
669688d4060Schristos     |	T_DLV sp rdata_unknown { if (dlv_warn) { dlv_warn = 0; zc_warning_prev_line("DLV is experimental"); } $$ = $1; parse_unknown_rdata($1, $3); }
670688d4060Schristos     |	T_SSHFP sp rdata_sshfp
671fb6f527bSchristos     |	T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); check_sshfp(); }
672688d4060Schristos     |	T_RRSIG sp rdata_rrsig
673688d4060Schristos     |	T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
674688d4060Schristos     |	T_NSEC sp rdata_nsec
675688d4060Schristos     |	T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
676688d4060Schristos     |	T_NSEC3 sp rdata_nsec3
677688d4060Schristos     |	T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
678688d4060Schristos     |	T_NSEC3PARAM sp rdata_nsec3_param
679688d4060Schristos     |	T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
680688d4060Schristos     |	T_DNSKEY sp rdata_dnskey
681688d4060Schristos     |	T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
682688d4060Schristos     |	T_TLSA sp rdata_tlsa
683688d4060Schristos     |	T_TLSA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
684d20bac77Schristos     |	T_SMIMEA sp rdata_smimea
685d20bac77Schristos     |	T_SMIMEA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
686688d4060Schristos     |	T_NID sp rdata_nid
687688d4060Schristos     |	T_NID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
688688d4060Schristos     |	T_L32 sp rdata_l32
689688d4060Schristos     |	T_L32 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
690688d4060Schristos     |	T_L64 sp rdata_l64
691688d4060Schristos     |	T_L64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
692688d4060Schristos     |	T_LP sp rdata_lp
693688d4060Schristos     |	T_LP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
694688d4060Schristos     |	T_EUI48 sp rdata_eui48
695688d4060Schristos     |	T_EUI48 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
696688d4060Schristos     |	T_EUI64 sp rdata_eui64
697688d4060Schristos     |	T_EUI64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
698688d4060Schristos     |	T_CAA sp rdata_caa
699688d4060Schristos     |	T_CAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
700688d4060Schristos     |	T_CDS sp rdata_ds
701688d4060Schristos     |	T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
702688d4060Schristos     |	T_CDNSKEY sp rdata_dnskey
703688d4060Schristos     |	T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
704688d4060Schristos     |	T_OPENPGPKEY sp rdata_openpgpkey
705688d4060Schristos     |	T_OPENPGPKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
706688d4060Schristos     |	T_CSYNC sp rdata_csync
707688d4060Schristos     |	T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
7085004c526Schristos     |	T_ZONEMD sp rdata_zonemd
7095004c526Schristos     |	T_ZONEMD sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
710*66a1527dSchristos     |	T_SVCB sp rdata_svcb
711*66a1527dSchristos     |	T_SVCB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
712*66a1527dSchristos     |	T_HTTPS sp rdata_svcb
713*66a1527dSchristos     |	T_HTTPS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
714688d4060Schristos     |	T_URI sp rdata_uri
715688d4060Schristos     |	T_URI sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
716688d4060Schristos     |	T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); }
717*66a1527dSchristos     |	str error NL
718688d4060Schristos     {
719688d4060Schristos 	    zc_error_prev_line("unrecognized RR type '%s'", $1.str);
720688d4060Schristos     }
721688d4060Schristos     ;
722688d4060Schristos 
723688d4060Schristos /*
724688d4060Schristos  *
725688d4060Schristos  * below are all the definition for all the different rdata
726688d4060Schristos  *
727688d4060Schristos  */
728688d4060Schristos 
729688d4060Schristos rdata_a:	dotted_str trail
730688d4060Schristos     {
731688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str));
732688d4060Schristos     }
733688d4060Schristos     ;
734688d4060Schristos 
735688d4060Schristos rdata_domain_name:	dname trail
736688d4060Schristos     {
737688d4060Schristos 	    /* convert a single dname record */
738688d4060Schristos 	    zadd_rdata_domain($1);
739688d4060Schristos     }
740688d4060Schristos     ;
741688d4060Schristos 
742*66a1527dSchristos rdata_soa:	dname sp dname sp str sp str sp str sp str sp str trail
743688d4060Schristos     {
744688d4060Schristos 	    /* convert the soa data */
745688d4060Schristos 	    zadd_rdata_domain($1);	/* prim. ns */
746688d4060Schristos 	    zadd_rdata_domain($3);	/* email */
747688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */
748688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */
749688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */
750688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */
751688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */
752688d4060Schristos     }
753688d4060Schristos     ;
754688d4060Schristos 
755*66a1527dSchristos rdata_wks:	dotted_str sp str sp concatenated_str_seq trail
756688d4060Schristos     {
757688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */
758688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */
759688d4060Schristos     }
760688d4060Schristos     ;
761688d4060Schristos 
762*66a1527dSchristos rdata_hinfo:	str sp str trail
763688d4060Schristos     {
764688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */
765688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/
766688d4060Schristos     }
767688d4060Schristos     ;
768688d4060Schristos 
769688d4060Schristos rdata_minfo:	dname sp dname trail
770688d4060Schristos     {
771688d4060Schristos 	    /* convert a single dname record */
772688d4060Schristos 	    zadd_rdata_domain($1);
773688d4060Schristos 	    zadd_rdata_domain($3);
774688d4060Schristos     }
775688d4060Schristos     ;
776688d4060Schristos 
777*66a1527dSchristos rdata_mx:	str sp dname trail
778688d4060Schristos     {
779688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* priority */
780688d4060Schristos 	    zadd_rdata_domain($3);	/* MX host */
781688d4060Schristos     }
782688d4060Schristos     ;
783688d4060Schristos 
784688d4060Schristos rdata_txt:	str_seq trail
785688d4060Schristos     {
786688d4060Schristos 	zadd_rdata_txt_clean_wireformat();
787688d4060Schristos     }
788688d4060Schristos     ;
789688d4060Schristos 
790688d4060Schristos /* RFC 1183 */
791688d4060Schristos rdata_rp:	dname sp dname trail
792688d4060Schristos     {
793688d4060Schristos 	    zadd_rdata_domain($1); /* mbox d-name */
794688d4060Schristos 	    zadd_rdata_domain($3); /* txt d-name */
795688d4060Schristos     }
796688d4060Schristos     ;
797688d4060Schristos 
798688d4060Schristos /* RFC 1183 */
799*66a1527dSchristos rdata_afsdb:	str sp dname trail
800688d4060Schristos     {
801688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */
802688d4060Schristos 	    zadd_rdata_domain($3); /* domain name */
803688d4060Schristos     }
804688d4060Schristos     ;
805688d4060Schristos 
806688d4060Schristos /* RFC 1183 */
807*66a1527dSchristos rdata_x25:	str trail
808688d4060Schristos     {
809688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */
810688d4060Schristos     }
811688d4060Schristos     ;
812688d4060Schristos 
813688d4060Schristos /* RFC 1183 */
814*66a1527dSchristos rdata_isdn:	str trail
815688d4060Schristos     {
816688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
817688d4060Schristos     }
818*66a1527dSchristos     |	str sp str trail
819688d4060Schristos     {
820688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */
821688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */
822688d4060Schristos     }
823688d4060Schristos     ;
824688d4060Schristos 
825688d4060Schristos /* RFC 1183 */
826*66a1527dSchristos rdata_rt:	str sp dname trail
827688d4060Schristos     {
828688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
829688d4060Schristos 	    zadd_rdata_domain($3); /* intermediate host */
830688d4060Schristos     }
831688d4060Schristos     ;
832688d4060Schristos 
833688d4060Schristos /* RFC 1706 */
834688d4060Schristos rdata_nsap:	str_dot_seq trail
835688d4060Schristos     {
836688d4060Schristos 	    /* String must start with "0x" or "0X".	 */
837688d4060Schristos 	    if (strncasecmp($1.str, "0x", 2) != 0) {
838688d4060Schristos 		    zc_error_prev_line("NSAP rdata must start with '0x'");
839688d4060Schristos 	    } else {
840688d4060Schristos 		    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */
841688d4060Schristos 	    }
842688d4060Schristos     }
843688d4060Schristos     ;
844688d4060Schristos 
845688d4060Schristos /* RFC 2163 */
846*66a1527dSchristos rdata_px:	str sp dname sp dname trail
847688d4060Schristos     {
848688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
849688d4060Schristos 	    zadd_rdata_domain($3); /* MAP822 */
850688d4060Schristos 	    zadd_rdata_domain($5); /* MAPX400 */
851688d4060Schristos     }
852688d4060Schristos     ;
853688d4060Schristos 
854688d4060Schristos rdata_aaaa:	dotted_str trail
855688d4060Schristos     {
856688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str));  /* IPv6 address */
857688d4060Schristos     }
858688d4060Schristos     ;
859688d4060Schristos 
860688d4060Schristos rdata_loc:	concatenated_str_seq trail
861688d4060Schristos     {
862688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */
863688d4060Schristos     }
864688d4060Schristos     ;
865688d4060Schristos 
866688d4060Schristos rdata_nxt:	dname sp nxt_seq trail
867688d4060Schristos     {
868688d4060Schristos 	    zadd_rdata_domain($1); /* nxt name */
869688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */
870688d4060Schristos 	    memset(nxtbits, 0, sizeof(nxtbits));
871688d4060Schristos     }
872688d4060Schristos     ;
873688d4060Schristos 
874*66a1527dSchristos rdata_srv:	str sp str sp str sp dname trail
875688d4060Schristos     {
876688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */
877688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
878688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */
879688d4060Schristos 	    zadd_rdata_domain($7); /* target name */
880688d4060Schristos     }
881688d4060Schristos     ;
882688d4060Schristos 
883688d4060Schristos /* RFC 2915 */
884*66a1527dSchristos rdata_naptr:	str sp str sp str sp str sp str sp dname trail
885688d4060Schristos     {
886688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */
887688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */
888688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */
889688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */
890688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */
891688d4060Schristos 	    zadd_rdata_domain($11); /* target name */
892688d4060Schristos     }
893688d4060Schristos     ;
894688d4060Schristos 
895688d4060Schristos /* RFC 2230 */
896*66a1527dSchristos rdata_kx:	str sp dname trail
897688d4060Schristos     {
898688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */
899688d4060Schristos 	    zadd_rdata_domain($3); /* exchanger */
900688d4060Schristos     }
901688d4060Schristos     ;
902688d4060Schristos 
903688d4060Schristos /* RFC 2538 */
904*66a1527dSchristos rdata_cert:	str sp str sp str sp str_sp_seq trail
905688d4060Schristos     {
906688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */
907688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */
908688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */
909688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */
910688d4060Schristos     }
911688d4060Schristos     ;
912688d4060Schristos 
913688d4060Schristos /* RFC 3123 */
914688d4060Schristos rdata_apl:	rdata_apl_seq trail
915688d4060Schristos     ;
916688d4060Schristos 
917688d4060Schristos rdata_apl_seq:	dotted_str
918688d4060Schristos     {
919688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str));
920688d4060Schristos     }
921688d4060Schristos     |	rdata_apl_seq sp dotted_str
922688d4060Schristos     {
923688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str));
924688d4060Schristos     }
925688d4060Schristos     ;
926688d4060Schristos 
927*66a1527dSchristos rdata_ds:	str sp str sp str sp str_sp_seq trail
928688d4060Schristos     {
929688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
930688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
931688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
932688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
933688d4060Schristos     }
934688d4060Schristos     ;
935688d4060Schristos 
936*66a1527dSchristos rdata_dlv:	str sp str sp str sp str_sp_seq trail
937688d4060Schristos     {
938688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */
939688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
940688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */
941688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */
942688d4060Schristos     }
943688d4060Schristos     ;
944688d4060Schristos 
945*66a1527dSchristos rdata_sshfp:	str sp str sp str_sp_seq trail
946688d4060Schristos     {
947688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */
948688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */
949688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */
950fb6f527bSchristos 	    check_sshfp();
951688d4060Schristos     }
952688d4060Schristos     ;
953688d4060Schristos 
954688d4060Schristos rdata_dhcid:	str_sp_seq trail
955688d4060Schristos     {
956688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */
957688d4060Schristos     }
958688d4060Schristos     ;
959688d4060Schristos 
960*66a1527dSchristos rdata_rrsig:	str sp str sp str sp str sp str sp str sp str sp wire_dname sp str_sp_seq trail
961688d4060Schristos     {
962688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_rrtype(parser->region, $1.str)); /* rr covered */
963688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */
964688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */
965688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */
966688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */
967688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */
968688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */
969688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
970688d4060Schristos 				(const uint8_t*) $15.str,$15.len)); /* sig name */
971688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */
972688d4060Schristos     }
973688d4060Schristos     ;
974688d4060Schristos 
975688d4060Schristos rdata_nsec:	wire_dname nsec_seq
976688d4060Schristos     {
977688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_dns_name(parser->region,
978688d4060Schristos 				(const uint8_t*) $1.str, $1.len)); /* nsec name */
979688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
980688d4060Schristos 	    memset(nsecbits, 0, sizeof(nsecbits));
981688d4060Schristos             nsec_highest_rcode = 0;
982688d4060Schristos     }
983688d4060Schristos     ;
984688d4060Schristos 
985*66a1527dSchristos rdata_nsec3:   str sp str sp str sp str sp str nsec_seq
986688d4060Schristos     {
987688d4060Schristos #ifdef NSEC3
988688d4060Schristos 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
989688d4060Schristos 
990688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */
991688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
992688d4060Schristos 	    memset(nsecbits, 0, sizeof(nsecbits));
993688d4060Schristos 	    nsec_highest_rcode = 0;
994688d4060Schristos #else
995688d4060Schristos 	    zc_error_prev_line("nsec3 not supported");
996688d4060Schristos #endif /* NSEC3 */
997688d4060Schristos     }
998688d4060Schristos     ;
999688d4060Schristos 
1000*66a1527dSchristos rdata_nsec3_param:   str sp str sp str sp str trail
1001688d4060Schristos     {
1002688d4060Schristos #ifdef NSEC3
1003688d4060Schristos 	    nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len);
1004688d4060Schristos #else
1005688d4060Schristos 	    zc_error_prev_line("nsec3 not supported");
1006688d4060Schristos #endif /* NSEC3 */
1007688d4060Schristos     }
1008688d4060Schristos     ;
1009688d4060Schristos 
1010*66a1527dSchristos rdata_tlsa:	str sp str sp str sp str_sp_seq trail
1011688d4060Schristos     {
1012688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1013688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1014688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1015688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1016688d4060Schristos     }
1017688d4060Schristos     ;
1018688d4060Schristos 
1019*66a1527dSchristos rdata_smimea:	str sp str sp str sp str_sp_seq trail
1020d20bac77Schristos     {
1021d20bac77Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */
1022d20bac77Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */
1023d20bac77Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */
1024d20bac77Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */
1025d20bac77Schristos     }
1026d20bac77Schristos     ;
1027d20bac77Schristos 
1028*66a1527dSchristos rdata_dnskey:	str sp str sp str sp str_sp_seq trail
1029688d4060Schristos     {
1030688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */
1031688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */
1032688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */
1033688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */
1034688d4060Schristos     }
1035688d4060Schristos     ;
1036688d4060Schristos 
1037*66a1527dSchristos rdata_ipsec_base: str sp str sp str sp dotted_str
1038688d4060Schristos     {
1039688d4060Schristos 	    const dname_type* name = 0;
1040688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */
1041688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */
1042688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */
1043688d4060Schristos 	    switch(atoi($3.str)) {
1044688d4060Schristos 		case IPSECKEY_NOGATEWAY:
1045688d4060Schristos 			zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0));
1046688d4060Schristos 			break;
1047688d4060Schristos 		case IPSECKEY_IP4:
1048688d4060Schristos 			zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str));
1049688d4060Schristos 			break;
1050688d4060Schristos 		case IPSECKEY_IP6:
1051688d4060Schristos 			zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $7.str));
1052688d4060Schristos 			break;
1053688d4060Schristos 		case IPSECKEY_DNAME:
1054688d4060Schristos 			/* convert and insert the dname */
1055688d4060Schristos 			if(strlen($7.str) == 0)
1056688d4060Schristos 				zc_error_prev_line("IPSECKEY must specify gateway name");
1057cd92f1a1Sprlw1 			if(!(name = dname_parse(parser->region, $7.str))) {
1058688d4060Schristos 				zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str);
1059cd92f1a1Sprlw1 				break;
1060cd92f1a1Sprlw1 			}
1061688d4060Schristos 			if($7.str[strlen($7.str)-1] != '.') {
1062688d4060Schristos 				if(parser->origin == error_domain) {
1063688d4060Schristos 		    			zc_error("cannot concatenate origin to domain name, because origin failed to parse");
1064688d4060Schristos 					break;
1065fb6f527bSchristos 				} else if(name->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) {
1066fb6f527bSchristos 					zc_error("ipsec gateway name exceeds %d character limit",
1067fb6f527bSchristos 						MAXDOMAINLEN);
1068fb6f527bSchristos 					break;
1069688d4060Schristos 				}
1070688d4060Schristos 				name = dname_concatenate(parser->rr_region, name,
1071688d4060Schristos 					domain_dname(parser->origin));
1072688d4060Schristos 			}
1073688d4060Schristos 			zadd_rdata_wireformat(alloc_rdata_init(parser->region,
1074688d4060Schristos 				dname_name(name), name->name_size));
1075688d4060Schristos 			break;
1076688d4060Schristos 		default:
1077688d4060Schristos 			zc_error_prev_line("unknown IPSECKEY gateway type");
1078688d4060Schristos 	    }
1079688d4060Schristos     }
1080688d4060Schristos     ;
1081688d4060Schristos 
1082688d4060Schristos rdata_ipseckey:	rdata_ipsec_base sp str_sp_seq trail
1083688d4060Schristos     {
1084688d4060Schristos 	   zadd_rdata_wireformat(zparser_conv_b64(parser->region, $3.str)); /* public key */
1085688d4060Schristos     }
1086688d4060Schristos     | rdata_ipsec_base trail
1087688d4060Schristos     ;
1088688d4060Schristos 
1089688d4060Schristos /* RFC 6742 */
1090*66a1527dSchristos rdata_nid:	str sp dotted_str trail
1091688d4060Schristos     {
1092688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1093688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* NodeID */
1094688d4060Schristos     }
1095688d4060Schristos     ;
1096688d4060Schristos 
1097*66a1527dSchristos rdata_l32:	str sp dotted_str trail
1098688d4060Schristos     {
1099688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1100688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str));  /* Locator32 */
1101688d4060Schristos     }
1102688d4060Schristos     ;
1103688d4060Schristos 
1104*66a1527dSchristos rdata_l64:	str sp dotted_str trail
1105688d4060Schristos     {
1106688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1107688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str));  /* Locator64 */
1108688d4060Schristos     }
1109688d4060Schristos     ;
1110688d4060Schristos 
1111*66a1527dSchristos rdata_lp:	str sp dname trail
1112688d4060Schristos     {
1113688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));  /* preference */
1114688d4060Schristos 	    zadd_rdata_domain($3);  /* FQDN */
1115688d4060Schristos     }
1116688d4060Schristos     ;
1117688d4060Schristos 
1118*66a1527dSchristos rdata_eui48:	str trail
1119688d4060Schristos     {
1120688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48));
1121688d4060Schristos     }
1122688d4060Schristos     ;
1123688d4060Schristos 
1124*66a1527dSchristos rdata_eui64:	str trail
1125688d4060Schristos     {
1126688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64));
1127688d4060Schristos     }
1128688d4060Schristos     ;
1129688d4060Schristos 
1130688d4060Schristos /* RFC7553 */
1131*66a1527dSchristos rdata_uri:	str sp str sp dotted_str trail
1132688d4060Schristos     {
1133688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */
1134688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */
1135688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */
1136688d4060Schristos     }
1137688d4060Schristos     ;
1138688d4060Schristos 
1139688d4060Schristos /* RFC 6844 */
1140*66a1527dSchristos rdata_caa:	str sp str sp dotted_str trail
1141688d4060Schristos     {
1142688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */
1143688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */
1144688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */
1145688d4060Schristos     }
1146688d4060Schristos     ;
1147688d4060Schristos 
1148688d4060Schristos /* RFC7929 */
1149688d4060Schristos rdata_openpgpkey:	str_sp_seq trail
1150688d4060Schristos     {
1151688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str));
1152688d4060Schristos     }
1153688d4060Schristos     ;
1154688d4060Schristos 
1155688d4060Schristos /* RFC7477 */
1156*66a1527dSchristos rdata_csync:	str sp str nsec_seq
1157688d4060Schristos     {
1158688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str));
1159688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str));
1160688d4060Schristos 	    zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */
1161688d4060Schristos 	    memset(nsecbits, 0, sizeof(nsecbits));
1162688d4060Schristos             nsec_highest_rcode = 0;
1163688d4060Schristos     }
1164688d4060Schristos     ;
1165688d4060Schristos 
11665004c526Schristos /* draft-ietf-dnsop-dns-zone-digest */
1167*66a1527dSchristos rdata_zonemd:	str sp str sp str sp str_sp_seq trail
11685004c526Schristos     {
11695004c526Schristos 	    zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); /* serial */
11705004c526Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* scheme */
11715004c526Schristos 	    zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* hash algorithm */
11725004c526Schristos 	    zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* digest */
11735004c526Schristos     }
11745004c526Schristos     ;
11755004c526Schristos 
1176*66a1527dSchristos svcparam:	dotted_str QSTR
1177*66a1527dSchristos     {
1178*66a1527dSchristos 	zadd_rdata_wireformat(zparser_conv_svcbparam(
1179*66a1527dSchristos 		parser->region, $1.str, $1.len, $2.str, $2.len));
1180*66a1527dSchristos     }
1181*66a1527dSchristos     |		dotted_str
1182*66a1527dSchristos     {
1183*66a1527dSchristos 	zadd_rdata_wireformat(zparser_conv_svcbparam(
1184*66a1527dSchristos 		parser->region, $1.str, $1.len, NULL, 0));
1185*66a1527dSchristos     }
1186*66a1527dSchristos     ;
1187*66a1527dSchristos svcparams:	svcparam
1188*66a1527dSchristos     |		svcparams sp svcparam
1189*66a1527dSchristos     ;
1190*66a1527dSchristos /* draft-ietf-dnsop-svcb-https */
1191*66a1527dSchristos rdata_svcb_base:	str sp dname
1192*66a1527dSchristos     {
1193*66a1527dSchristos 	    /* SvcFieldPriority */
1194*66a1527dSchristos 	    zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str));
1195*66a1527dSchristos 	    /* SvcDomainName */
1196*66a1527dSchristos 	    zadd_rdata_domain($3);
1197*66a1527dSchristos     };
1198*66a1527dSchristos rdata_svcb:     rdata_svcb_base sp svcparams trail
1199*66a1527dSchristos     {
1200*66a1527dSchristos         zadd_rdata_svcb_check_wireformat();
1201*66a1527dSchristos     }
1202*66a1527dSchristos     |   rdata_svcb_base trail
1203*66a1527dSchristos     ;
1204*66a1527dSchristos 
1205*66a1527dSchristos rdata_unknown:	URR sp str sp str_sp_seq trail
1206688d4060Schristos     {
1207688d4060Schristos 	    /* $2 is the number of octets, currently ignored */
1208d20bac77Schristos 	    $$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len);
1209688d4060Schristos 
1210688d4060Schristos     }
1211*66a1527dSchristos     |	URR sp str trail
1212688d4060Schristos     {
1213d20bac77Schristos 	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1214688d4060Schristos     }
1215688d4060Schristos     |	URR error NL
1216688d4060Schristos     {
1217d20bac77Schristos 	    $$ = zparser_conv_hex(parser->rr_region, "", 0);
1218688d4060Schristos     }
1219688d4060Schristos     ;
1220688d4060Schristos %%
1221688d4060Schristos 
1222688d4060Schristos int
1223688d4060Schristos yywrap(void)
1224688d4060Schristos {
1225688d4060Schristos 	return 1;
1226688d4060Schristos }
1227688d4060Schristos 
1228688d4060Schristos /*
1229688d4060Schristos  * Create the parser.
1230688d4060Schristos  */
1231688d4060Schristos zparser_type *
zparser_create(region_type * region,region_type * rr_region,namedb_type * db)1232688d4060Schristos zparser_create(region_type *region, region_type *rr_region, namedb_type *db)
1233688d4060Schristos {
1234688d4060Schristos 	zparser_type *result;
1235688d4060Schristos 
1236688d4060Schristos 	result = (zparser_type *) region_alloc(region, sizeof(zparser_type));
1237688d4060Schristos 	result->region = region;
1238688d4060Schristos 	result->rr_region = rr_region;
1239688d4060Schristos 	result->db = db;
1240688d4060Schristos 
1241688d4060Schristos 	result->filename = NULL;
1242688d4060Schristos 	result->current_zone = NULL;
1243688d4060Schristos 	result->origin = NULL;
1244688d4060Schristos 	result->prev_dname = NULL;
1245688d4060Schristos 
1246688d4060Schristos 	result->temporary_rdatas = (rdata_atom_type *) region_alloc_array(
1247688d4060Schristos 		result->region, MAXRDATALEN, sizeof(rdata_atom_type));
1248688d4060Schristos 
1249688d4060Schristos 	return result;
1250688d4060Schristos }
1251688d4060Schristos 
1252688d4060Schristos /*
1253688d4060Schristos  * Initialize the parser for a new zone file.
1254688d4060Schristos  */
1255688d4060Schristos void
zparser_init(const char * filename,uint32_t ttl,uint16_t klass,const dname_type * origin)1256688d4060Schristos zparser_init(const char *filename, uint32_t ttl, uint16_t klass,
1257688d4060Schristos 	     const dname_type *origin)
1258688d4060Schristos {
1259688d4060Schristos 	memset(nxtbits, 0, sizeof(nxtbits));
1260688d4060Schristos 	memset(nsecbits, 0, sizeof(nsecbits));
1261688d4060Schristos         nsec_highest_rcode = 0;
1262688d4060Schristos 
1263688d4060Schristos 	parser->default_ttl = ttl;
1264688d4060Schristos 	parser->default_class = klass;
1265688d4060Schristos 	parser->current_zone = NULL;
1266688d4060Schristos 	parser->origin = domain_table_insert(parser->db->domains, origin);
1267688d4060Schristos 	parser->prev_dname = parser->origin;
1268688d4060Schristos 	parser->error_occurred = 0;
1269688d4060Schristos 	parser->errors = 0;
1270688d4060Schristos 	parser->line = 1;
1271688d4060Schristos 	parser->filename = filename;
1272688d4060Schristos 	parser->current_rr.rdata_count = 0;
1273688d4060Schristos 	parser->current_rr.rdatas = parser->temporary_rdatas;
1274688d4060Schristos }
1275688d4060Schristos 
1276688d4060Schristos void
yyerror(const char * message)1277688d4060Schristos yyerror(const char *message)
1278688d4060Schristos {
1279688d4060Schristos 	zc_error("%s", message);
1280688d4060Schristos }
1281688d4060Schristos 
1282688d4060Schristos static void
error_va_list(unsigned line,const char * fmt,va_list args)1283688d4060Schristos error_va_list(unsigned line, const char *fmt, va_list args)
1284688d4060Schristos {
1285688d4060Schristos 	if (parser->filename) {
1286688d4060Schristos 		char message[MAXSYSLOGMSGLEN];
1287688d4060Schristos 		vsnprintf(message, sizeof(message), fmt, args);
1288688d4060Schristos 		log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message);
1289688d4060Schristos 	}
1290688d4060Schristos 	else log_vmsg(LOG_ERR, fmt, args);
1291688d4060Schristos 
1292688d4060Schristos 	++parser->errors;
1293688d4060Schristos 	parser->error_occurred = 1;
1294688d4060Schristos }
1295688d4060Schristos 
1296688d4060Schristos /* the line counting sux, to say the least
1297688d4060Schristos  * with this grose hack we try do give sane
1298688d4060Schristos  * numbers back */
1299688d4060Schristos void
zc_error_prev_line(const char * fmt,...)1300688d4060Schristos zc_error_prev_line(const char *fmt, ...)
1301688d4060Schristos {
1302688d4060Schristos 	va_list args;
1303688d4060Schristos 	va_start(args, fmt);
1304688d4060Schristos 	error_va_list(parser->line - 1, fmt, args);
1305688d4060Schristos 	va_end(args);
1306688d4060Schristos }
1307688d4060Schristos 
1308688d4060Schristos void
zc_error(const char * fmt,...)1309688d4060Schristos zc_error(const char *fmt, ...)
1310688d4060Schristos {
1311688d4060Schristos 	/* send an error message to stderr */
1312688d4060Schristos 	va_list args;
1313688d4060Schristos 	va_start(args, fmt);
1314688d4060Schristos 	error_va_list(parser->line, fmt, args);
1315688d4060Schristos 	va_end(args);
1316688d4060Schristos }
1317688d4060Schristos 
1318688d4060Schristos static void
warning_va_list(unsigned line,const char * fmt,va_list args)1319688d4060Schristos warning_va_list(unsigned line, const char *fmt, va_list args)
1320688d4060Schristos {
1321688d4060Schristos 	if (parser->filename) {
1322688d4060Schristos 		char m[MAXSYSLOGMSGLEN];
1323688d4060Schristos 		vsnprintf(m, sizeof(m), fmt, args);
1324688d4060Schristos 		log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m);
1325688d4060Schristos 	}
1326688d4060Schristos 	else log_vmsg(LOG_WARNING, fmt, args);
1327688d4060Schristos }
1328688d4060Schristos 
1329688d4060Schristos void
zc_warning_prev_line(const char * fmt,...)1330688d4060Schristos zc_warning_prev_line(const char *fmt, ...)
1331688d4060Schristos {
1332688d4060Schristos 	va_list args;
1333688d4060Schristos 	va_start(args, fmt);
1334688d4060Schristos 	warning_va_list(parser->line - 1, fmt, args);
1335688d4060Schristos 	va_end(args);
1336688d4060Schristos }
1337688d4060Schristos 
1338688d4060Schristos void
zc_warning(const char * fmt,...)1339688d4060Schristos zc_warning(const char *fmt, ... )
1340688d4060Schristos {
1341688d4060Schristos 	va_list args;
1342688d4060Schristos 	va_start(args, fmt);
1343688d4060Schristos 	warning_va_list(parser->line, fmt, args);
1344688d4060Schristos 	va_end(args);
1345688d4060Schristos }
1346688d4060Schristos 
1347688d4060Schristos #ifdef NSEC3
1348688d4060Schristos static void
nsec3_add_params(const char * hashalgo_str,const char * flag_str,const char * iter_str,const char * salt_str,int salt_len)1349688d4060Schristos nsec3_add_params(const char* hashalgo_str, const char* flag_str,
1350688d4060Schristos 	const char* iter_str, const char* salt_str, int salt_len)
1351688d4060Schristos {
1352688d4060Schristos 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, hashalgo_str));
1353688d4060Schristos 	zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str));
1354688d4060Schristos 	zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str));
1355688d4060Schristos 
1356688d4060Schristos 	/* salt */
1357688d4060Schristos 	if(strcmp(salt_str, "-") != 0)
1358688d4060Schristos 		zadd_rdata_wireformat(zparser_conv_hex_length(parser->region,
1359688d4060Schristos 			salt_str, salt_len));
1360688d4060Schristos 	else
1361688d4060Schristos 		zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1));
1362688d4060Schristos }
1363688d4060Schristos #endif /* NSEC3 */
1364