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