1 /*
2  * Copyright (C) 2004-2011, 2014, 2015  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 
59 typedef struct cfg_clausedef cfg_clausedef_t;
60 typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
61 typedef struct cfg_printer cfg_printer_t;
62 typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
63 typedef struct cfg_map cfg_map_t;
64 typedef struct cfg_rep cfg_rep_t;
65 
66 /*
67  * Function types for configuration object methods
68  */
69 
70 typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
71 					cfg_obj_t **);
72 typedef void	     (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
73 typedef void	     (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
74 typedef 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  */
85 struct cfg_printer {
86 	void (*f)(void *closure, const char *text, int textlen);
87 	void *closure;
88 	int indent;
89 	int flags;
90 };
91 
92 /*% A clause definition. */
93 struct cfg_clausedef {
94 	const char      *name;
95 	cfg_type_t      *type;
96 	unsigned int	flags;
97 };
98 
99 /*% A tuple field definition. */
100 struct cfg_tuplefielddef {
101 	const char      *name;
102 	cfg_type_t      *type;
103 	unsigned int	flags;
104 };
105 
106 /*% A configuration object type definition. */
107 struct cfg_type {
108 	const char *name;	/*%< For debugging purposes only */
109 	cfg_parsefunc_t	parse;
110 	cfg_printfunc_t print;
111 	cfg_docfunc_t	doc;	/*%< Print grammar description */
112 	cfg_rep_t *	rep;	/*%< Data representation */
113 	const void *	of;	/*%< Additional data for meta-types */
114 };
115 
116 /*% A keyword-type definition, for things like "port <integer>". */
117 typedef struct {
118 	const char *name;
119 	const cfg_type_t *type;
120 } keyword_type_t;
121 
122 struct cfg_map {
123 	cfg_obj_t	 *id; /*%< Used for 'named maps' like keys, zones, &c */
124 	const cfg_clausedef_t * const *clausesets; /*%< The clauses that
125 						      can occur in this map;
126 						      used for printing */
127 	isc_symtab_t     *symtab;
128 };
129 
130 typedef struct cfg_netprefix cfg_netprefix_t;
131 
132 struct cfg_netprefix {
133 	isc_netaddr_t address; /* IP4/IP6 */
134 	unsigned int prefixlen;
135 };
136 
137 /*%
138  * A configuration data representation.
139  */
140 struct cfg_rep {
141 	const char *	name;	/*%< For debugging only */
142 	cfg_freefunc_t 	free;	/*%< How to free this kind of data. */
143 };
144 
145 /*%
146  * A configuration object.  This is the main building block
147  * of the configuration parse tree.
148  */
149 
150 struct cfg_obj {
151 	const cfg_type_t *type;
152 	union {
153 		isc_uint32_t  	uint32;
154 		isc_uint64_t  	uint64;
155 		isc_textregion_t string; /*%< null terminated, too */
156 		isc_boolean_t 	boolean;
157 		cfg_map_t	map;
158 		cfg_list_t	list;
159 		cfg_obj_t **	tuple;
160 		isc_sockaddr_t	sockaddr;
161 		cfg_netprefix_t netprefix;
162 	}               value;
163 	isc_refcount_t  references;     /*%< reference counter */
164 	const char *	file;
165 	unsigned int    line;
166 };
167 
168 
169 /*% A list element. */
170 struct cfg_listelt {
171 	cfg_obj_t               *obj;
172 	ISC_LINK(cfg_listelt_t)  link;
173 };
174 
175 /*% The parser object. */
176 struct cfg_parser {
177 	isc_mem_t *	mctx;
178 	isc_log_t *	lctx;
179 	isc_lex_t *	lexer;
180 	unsigned int    errors;
181 	unsigned int    warnings;
182 	isc_token_t     token;
183 
184 	/*% We are at the end of all input. */
185 	isc_boolean_t	seen_eof;
186 
187 	/*% The current token has been pushed back. */
188 	isc_boolean_t	ungotten;
189 
190 	/*%
191 	 * The stack of currently active files, represented
192 	 * as a configuration list of configuration strings.
193 	 * The head is the top-level file, subsequent elements
194 	 * (if any) are the nested include files, and the
195 	 * last element is the file currently being parsed.
196 	 */
197 	cfg_obj_t *	open_files;
198 
199 	/*%
200 	 * Names of files that we have parsed and closed
201 	 * and were previously on the open_file list.
202 	 * We keep these objects around after closing
203 	 * the files because the file names may still be
204 	 * referenced from other configuration objects
205 	 * for use in reporting semantic errors after
206 	 * parsing is complete.
207 	 */
208 	cfg_obj_t *	closed_files;
209 
210 	/*%
211 	 * Current line number.  We maintain our own
212 	 * copy of this so that it is available even
213 	 * when a file has just been closed.
214 	 */
215 	unsigned int	line;
216 
217 	/*%
218 	 * Parser context flags, used for maintaining state
219 	 * from one token to the next.
220 	 */
221 	unsigned int flags;
222 
223 	/*%< Reference counter */
224 	isc_refcount_t  references;
225 
226 	cfg_parsecallback_t callback;
227 	void *callbackarg;
228 };
229 
230 /* Parser context flags */
231 #define CFG_PCTX_SKIP		0x1
232 
233 /*@{*/
234 /*%
235  * Flags defining whether to accept certain types of network addresses.
236  */
237 #define CFG_ADDR_V4OK 		0x00000001
238 #define CFG_ADDR_V4PREFIXOK 	0x00000002
239 #define CFG_ADDR_V6OK 		0x00000004
240 #define CFG_ADDR_WILDOK		0x00000008
241 #define CFG_ADDR_MASK		(CFG_ADDR_V6OK|CFG_ADDR_V4OK)
242 /*@}*/
243 
244 /*@{*/
245 /*%
246  * Predefined data representation types.
247  */
248 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32;
249 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64;
250 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string;
251 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean;
252 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map;
253 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list;
254 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple;
255 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr;
256 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
257 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
258 LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
259 /*@}*/
260 
261 /*@{*/
262 /*%
263  * Predefined configuration object types.
264  */
265 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean;
266 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32;
267 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64;
268 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring;
269 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
270 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
271 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring;
272 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
273 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
274 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
275 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
276 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
277 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
278 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
279 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
280 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
281 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
282 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
283 /*@}*/
284 
285 isc_result_t
286 cfg_gettoken(cfg_parser_t *pctx, int options);
287 
288 isc_result_t
289 cfg_peektoken(cfg_parser_t *pctx, int options);
290 
291 void
292 cfg_ungettoken(cfg_parser_t *pctx);
293 
294 #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
295 
296 isc_result_t
297 cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
298 
299 void
300 cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
301 
302 isc_result_t
303 cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
304 
305 void
306 cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj);
307 
308 void
309 cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj);
310 
311 isc_result_t
312 cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
313 
314 void
315 cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj);
316 
317 isc_result_t
318 cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
319 
320 isc_result_t
321 cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
322 
323 isc_result_t
324 cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na);
325 
326 void
327 cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na);
328 
329 isc_boolean_t
330 cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags);
331 
332 isc_result_t
333 cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
334 
335 isc_result_t
336 cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
337 
338 isc_result_t
339 cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
340 
341 void
342 cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
343 
344 void
345 cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
346 
347 void
348 cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
349 
350 isc_result_t
351 cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
352 
353 isc_result_t
354 cfg_parse_special(cfg_parser_t *pctx, int special);
355 /*%< Parse a required special character 'special'. */
356 
357 isc_result_t
358 cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
359 
360 isc_result_t
361 cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
362 
363 void
364 cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
365 
366 void
367 cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
368 
369 isc_result_t
370 cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
371 
372 isc_result_t
373 cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
374 		  cfg_listelt_t **ret);
375 
376 isc_result_t
377 cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
378 
379 void
380 cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj);
381 
382 void
383 cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type);
384 
385 isc_result_t
386 cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
387 
388 void
389 cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj);
390 
391 isc_result_t
392 cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
393 
394 void
395 cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
396 
397 void
398 cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
399 /*%< Print 'len' characters at 'text' */
400 
401 void
402 cfg_print_cstr(cfg_printer_t *pctx, const char *s);
403 /*%< Print the null-terminated string 's' */
404 
405 isc_result_t
406 cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
407 
408 isc_result_t
409 cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
410 
411 isc_result_t
412 cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
413 
414 isc_result_t
415 cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **
416 ret);
417 
418 void
419 cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj);
420 
421 void
422 cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type);
423 
424 isc_result_t
425 cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
426 
427 void
428 cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj);
429 
430 void
431 cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type);
432 
433 isc_result_t
434 cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
435 
436 void
437 cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj);
438 
439 void
440 cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type);
441 
442 isc_result_t
443 cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
444 
445 void
446 cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj);
447 
448 isc_result_t
449 cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
450 
451 void
452 cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj);
453 
454 void
455 cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type);
456 /*%<
457  * Print a description of the grammar of an arbitrary configuration
458  * type 'type'
459  */
460 
461 void
462 cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type);
463 /*%<
464  * Document the type 'type' as a terminal by printing its
465  * name in angle brackets, e.g., &lt;uint32>.
466  */
467 
468 void
469 cfg_parser_error(cfg_parser_t *pctx, unsigned int flags,
470 		 const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
471 /*!
472  * Pass one of these flags to cfg_parser_error() to include the
473  * token text in log message.
474  */
475 #define CFG_LOG_NEAR    0x00000001	/*%< Say "near <token>" */
476 #define CFG_LOG_BEFORE  0x00000002	/*%< Say "before <token>" */
477 #define CFG_LOG_NOPREP  0x00000004	/*%< Say just "<token>" */
478 
479 void
480 cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags,
481 		   const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4);
482 
483 isc_boolean_t
484 cfg_is_enum(const char *s, const char *const *enums);
485 /*%< Return true iff the string 's' is one of the strings in 'enums' */
486 
487 #endif /* ISCCFG_GRAMMAR_H */
488