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