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