diff options
Diffstat (limited to 'lib/isccfg/namedconf.c')
-rw-r--r-- | lib/isccfg/namedconf.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 21ab77ad..a7994b3f 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.78.46.7 2008/05/27 22:36:11 each Exp $ */ +/* $Id: namedconf.c,v 1.78.46.9 2008/06/24 23:46:27 tbox Exp $ */ /*! \file */ @@ -546,30 +546,80 @@ static cfg_type_t cfg_type_serverid = { /*% * Port list. */ +static cfg_tuplefielddef_t porttuple_fields[] = { + { "loport", &cfg_type_uint32, 0 }, + { "hiport", &cfg_type_uint32, 0 }, + { NULL, NULL, 0 } +}; +static cfg_type_t cfg_type_porttuple = { + "porttuple", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, + &cfg_rep_tuple, porttuple_fields +}; + static isc_result_t -parse_port(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { +parse_port(cfg_parser_t *pctx, cfg_obj_t **ret) { isc_result_t result; - UNUSED(type); - CHECK(cfg_parse_uint32(pctx, NULL, ret)); if ((*ret)->value.uint32 > 0xffff) { cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port"); cfg_obj_destroy(pctx, ret); result = ISC_R_RANGE; } + cleanup: return (result); } -static cfg_type_t cfg_type_port = { - "port", parse_port, NULL, cfg_doc_terminal, +static isc_result_t +parse_portrange(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { + isc_result_t result; + cfg_obj_t *obj = NULL; + + UNUSED(type); + + CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); + if (pctx->token.type == isc_tokentype_number) + CHECK(parse_port(pctx, ret)); + else { + CHECK(cfg_gettoken(pctx, 0)); + if (pctx->token.type != isc_tokentype_string || + strcasecmp(TOKEN_STRING(pctx), "range") != 0) { + cfg_parser_error(pctx, CFG_LOG_NEAR, + "expected integer or 'range'"); + return (ISC_R_UNEXPECTEDTOKEN); + } + CHECK(cfg_create_tuple(pctx, &cfg_type_porttuple, &obj)); + CHECK(parse_port(pctx, &obj->value.tuple[0])); + CHECK(parse_port(pctx, &obj->value.tuple[1])); + if (obj->value.tuple[0]->value.uint32 > + obj->value.tuple[1]->value.uint32) { + cfg_parser_error(pctx, CFG_LOG_NOPREP, + "low port '%u' must not be larger " + "than high port", + obj->value.tuple[0]->value.uint32); + result = ISC_R_RANGE; + goto cleanup; + } + *ret = obj; + obj = NULL; + } + + cleanup: + if (obj != NULL) + cfg_obj_destroy(pctx, &obj); + return (result); +} + +static cfg_type_t cfg_type_portrange = { + "portrange", parse_portrange, NULL, cfg_doc_terminal, NULL, NULL }; static cfg_type_t cfg_type_bracketed_portlist = { - "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_port + "bracketed_sockaddrlist", cfg_parse_bracketed_list, + cfg_print_bracketed_list, cfg_doc_bracketed_list, + &cfg_rep_list, &cfg_type_portrange }; /*% @@ -610,6 +660,8 @@ namedconf_or_view_clauses[] = { */ static cfg_clausedef_t options_clauses[] = { + { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, + { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "blackhole", &cfg_type_bracketed_aml, 0 }, |