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., <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