1/*
2 * Copyright (C) 2004-2011  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2002, 2003  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: grammar.h,v 1.24 2011/01/04 23:47:14 tbox Exp $ */
19
20#ifndef ISCCFG_GRAMMAR_H
21#define ISCCFG_GRAMMAR_H 1
22
23/*! \file isccfg/grammar.h */
24
25#include <isc/lex.h>
26#include <isc/netaddr.h>
27#include <isc/sockaddr.h>
28#include <isc/region.h>
29#include <isc/types.h>
30
31#include <isccfg/cfg.h>
32
33/*
34 * Definitions shared between the configuration parser
35 * and the grammars; not visible to users of the parser.
36 */
37
38/*% Clause may occur multiple times (e.g., "zone") */
39#define CFG_CLAUSEFLAG_MULTI 		0x00000001
40/*% Clause is obsolete */
41#define CFG_CLAUSEFLAG_OBSOLETE 	0x00000002
42/*% Clause is not implemented, and may never be */
43#define CFG_CLAUSEFLAG_NOTIMP	 	0x00000004
44/*% Clause is not implemented yet */
45#define CFG_CLAUSEFLAG_NYI 		0x00000008
46/*% Default value has changed since earlier release */
47#define CFG_CLAUSEFLAG_NEWDEFAULT	0x00000010
48/*%
49 * Clause needs to be interpreted during parsing
50 * by calling a callback function, like the
51 * "directory" option.
52 */
53#define CFG_CLAUSEFLAG_CALLBACK		0x00000020
54/*% A option that is only used in testing. */
55#define CFG_CLAUSEFLAG_TESTONLY		0x00000040
56/*% A configuration option that was not configured at compile time. */
57#define CFG_CLAUSEFLAG_NOTCONFIGURED	0x00000080
58
59typedef struct cfg_clausedef cfg_clausedef_t;
60typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
61typedef struct cfg_printer cfg_printer_t;
62typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
63typedef struct cfg_map cfg_map_t;
64typedef struct cfg_rep cfg_rep_t;
65
66/*
67 * Function types for configuration object methods
68 */
69
70typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
71					cfg_obj_t **);
72typedef void	     (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
73typedef void	     (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
74typedef void	     (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
75
76/*
77 * Structure definitions
78 */
79
80/*%
81 * A configuration printer object.  This is an abstract
82 * interface to a destination to which text can be printed
83 * by calling the function 'f'.
84 */
85struct cfg_printer {
86	void (*f)(void *closure, const char *text, int textlen);
87	void *closure;
88	int indent;
89};
90
91/*% A clause definition. */
92struct cfg_clausedef {
93	const char      *name;
94	cfg_type_t      *type;
95	unsigned int	flags;
96};
97
98/*% A tuple field definition. */
99struct cfg_tuplefielddef {
100	const char      *name;
101	cfg_type_t      *type;
102	unsigned int	flags;
103};
104
105/*% A configuration object type definition. */
106struct cfg_type {
107	const char *name;	/*%< For debugging purposes only */
108	cfg_parsefunc_t	parse;
109	cfg_printfunc_t print;
110	cfg_docfunc_t	doc;	/*%< Print grammar description */
111	cfg_rep_t *	rep;	/*%< Data representation */
112	const void *	of;	/*%< Additional data for meta-types */
113};
114
115/*% A keyword-type definition, for things like "port <integer>". */
116typedef struct {
117	const char *name;
118	const cfg_type_t *type;
119} keyword_type_t;
120
121struct cfg_map {
122	cfg_obj_t	 *id; /*%< Used for 'named maps' like keys, zones, &c */
123	const cfg_clausedef_t * const *clausesets; /*%< The clauses that
124						      can occur in this map;
125						      used for printing */
126	isc_symtab_t     *symtab;
127};
128
129typedef struct cfg_netprefix cfg_netprefix_t;
130
131struct cfg_netprefix {
132	isc_netaddr_t address; /* IP4/IP6 */
133	unsigned int prefixlen;
134};
135
136/*%
137 * A configuration data representation.
138 */
139struct cfg_rep {
140	const char *	name;	/*%< For debugging only */
141	cfg_freefunc_t 	free;	/*%< How to free this kind of data. */
142};
143
144/*%
145 * A configuration object.  This is the main building block
146 * of the configuration parse tree.
147 */
148
149struct cfg_obj {
150	const cfg_type_t *type;
151	union {
152		isc_uint32_t  	uint32;
153		isc_uint64_t  	uint64;
154		isc_textregion_t string; /*%< null terminated, too */
155		isc_boolean_t 	boolean;
156		cfg_map_t	map;
157		cfg_list_t	list;
158		cfg_obj_t **	tuple;
159		isc_sockaddr_t	sockaddr;
160		cfg_netprefix_t netprefix;
161	}               value;
162	isc_refcount_t  references;     /*%< reference counter */
163	const char *	file;
164	unsigned int    line;
165};
166
167
168/*% A list element. */
169struct cfg_listelt {
170	cfg_obj_t               *obj;
171	ISC_LINK(cfg_listelt_t)  link;
172};
173
174/*% The parser object. */
175struct cfg_parser {
176	isc_mem_t *	mctx;
177	isc_log_t *	lctx;
178	isc_lex_t *	lexer;
179	unsigned int    errors;
180	unsigned int    warnings;
181	isc_token_t     token;
182
183	/*% We are at the end of all input. */
184	isc_boolean_t	seen_eof;
185
186	/*% The current token has been pushed back. */
187	isc_boolean_t	ungotten;
188
189	/*%
190	 * The stack of currently active files, represented
191	 * as a configuration list of configuration strings.
192	 * The head is the top-level file, subsequent elements
193	 * (if any) are the nested include files, and the
194	 * last element is the file currently being parsed.
195	 */
196	cfg_obj_t *	open_files;
197
198	/*%
199	 * Names of files that we have parsed and closed
200	 * and were previously on the open_file list.
201	 * We keep these objects around after closing
202	 * the files because the file names may still be
203	 * referenced from other configuration objects
204	 * for use in reporting semantic errors after
205	 * parsing is complete.
206	 */
207	cfg_obj_t *	closed_files;
208
209	/*%
210	 * Current line number.  We maintain our own
211	 * copy of this so that it is available even
212	 * when a file has just been closed.
213	 */
214	unsigned int	line;
215
216	/*%
217	 * Parser context flags, used for maintaining state
218	 * from one token to the next.
219	 */
220	unsigned int flags;
221
222	/*%< Reference counter */
223	isc_refcount_t  references;
224
225	cfg_parsecallback_t callback;
226	void *callbackarg;
227};
228
229/* Parser context flags */
230#define CFG_PCTX_SKIP		0x1
231
232/*@{*/
233/*%
234 * Flags defining whether to accept certain types of network addresses.
235 */
236#define CFG_ADDR_V4OK 		0x00000001
237#define CFG_ADDR_V4PREFIXOK 	0x00000002
238#define CFG_ADDR_V6OK 		0x00000004
239#define CFG_ADDR_WILDOK		0x00000008
240#define CFG_ADDR_MASK		(CFG_ADDR_V6OK|CFG_ADDR_V4OK)
241/*@}*/
242
243/*@{*/
244/*%
245 * Predefined data representation types.
246 */
247LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
248LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
249LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
250LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
251LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
252LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
253LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
254LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
255LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
256LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
257/*@}*/
258
259/*@{*/
260/*%
261 * Predefined configuration object types.
262 */
263LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
264LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
265LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
266LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
267LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
268LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
269LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
270LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
271LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namesockaddrkey;
272LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namesockaddrkeylist;
273LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
274LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
275LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
276LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
277LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
278LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
279LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_optional_keyref;
280LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
281LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
282LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
283LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_implicitlist;
284/*@}*/
285
286isc_result_t
287cfg_gettoken(cfg_parser_t *pctx, int options);
288
289isc_result_t
290cfg_peektoken(cfg_parser_t *pctx, int options);
291
292void
293cfg_ungettoken(cfg_parser_t *pctx);
294
295#define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
296
297isc_result_t
298cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
299
300void
301cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
302
303isc_result_t
304cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
305
306void
307cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
308
309void
310cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
311
312isc_result_t
313cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
314
315void
316cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
317
318isc_result_t
319cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
320
321isc_result_t
322cfg_create_string(cfg_parser_t *pctx, const char* contents, const cfg_type_t *type, cfg_obj_t **ret);
323
324isc_result_t
325cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
326
327void
328cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
329
330isc_boolean_t
331cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
332
333isc_result_t
334cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
335
336isc_result_t
337cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
338
339isc_result_t
340cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
341
342void
343cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
344
345void
346cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
347
348void
349cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
350
351isc_result_t
352cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
353
354isc_result_t
355cfg_parse_special(cfg_parser_t *pctx, int special);
356/*%< Parse a required special character 'special'. */
357
358isc_result_t
359cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
360
361isc_result_t
362cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
363
364void
365cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
366
367void
368cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
369
370isc_result_t
371cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
372
373isc_result_t
374cfg_create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp);
375
376isc_result_t
377cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
378		  cfg_listelt_t **ret);
379
380isc_result_t
381cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
382
383void
384cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
385
386void
387cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
388
389isc_result_t
390cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
391
392void
393cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
394
395isc_result_t
396cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
397
398void
399cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
400
401void
402cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
403/*%< Print 'len' characters at 'text' */
404
405void
406cfg_print_cstr(cfg_printer_t *pctx, const char *s);
407/*%< Print the null-terminated string 's' */
408
409isc_result_t
410cfg_create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
411
412isc_result_t
413cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
414
415isc_result_t
416cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
417
418isc_result_t
419cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
420
421isc_result_t
422cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
423ret);
424
425void
426cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
427
428void
429cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
430
431isc_result_t
432cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
433
434void
435cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
436
437void
438cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
439
440isc_result_t
441cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
442
443void
444cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
445
446void
447cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
448
449isc_result_t
450cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
451
452void
453cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
454
455void
456cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
457/*%<
458 * Print a description of the grammar of an arbitrary configuration
459 * type 'type'
460 */
461
462void
463cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
464/*%<
465 * Document the type 'type' as a terminal by printing its
466 * name in angle brackets, e.g., &lt;uint32>.
467 */
468
469void
470cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
471		 const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
472/*!
473 * Pass one of these flags to cfg_parser_error() to include the
474 * token text in log message.
475 */
476#define CFG_LOG_NEAR    0x00000001	/*%< Say "near <token>" */
477#define CFG_LOG_BEFORE  0x00000002	/*%< Say "before <token>" */
478#define CFG_LOG_NOPREP  0x00000004	/*%< Say just "<token>" */
479
480void
481cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
482		   const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
483
484isc_boolean_t
485cfg_is_enum(const char *s, const char *const *enums);
486/*%< Return true iff the string 's' is one of the strings in 'enums' */
487
488#endif /* ISCCFG_GRAMMAR_H */
489