From f5f56e1a1c4d9e9496fcb9d81131066a964ccd23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:15:43 +0200 Subject: Adding upstream version 2.4.1. Signed-off-by: Daniel Baumann --- src/lib/eval/eval_context.cc | 260 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 src/lib/eval/eval_context.cc (limited to 'src/lib/eval/eval_context.cc') diff --git a/src/lib/eval/eval_context.cc b/src/lib/eval/eval_context.cc new file mode 100644 index 0000000..d91fbb0 --- /dev/null +++ b/src/lib/eval/eval_context.cc @@ -0,0 +1,260 @@ +// Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EvalContext::EvalContext(const Option::Universe& option_universe, + CheckDefined check_defined) + : trace_scanning_(false), trace_parsing_(false), + option_universe_(option_universe), check_defined_(check_defined) +{ +} + +EvalContext::~EvalContext() { +} + +bool +EvalContext::acceptAll(const ClientClass&) { + return (true); +} + +bool +EvalContext::parseString(const std::string& str, ParserType type) { + file_ = ""; + string_ = str; + scanStringBegin(type); + int res = -1; + try { + isc::eval::EvalParser parser(*this); + parser.set_debug_level(trace_parsing_); + res = parser.parse(); + } catch (...) { + scanStringEnd(); + throw; + } + scanStringEnd(); + return (res == 0); +} + +void +EvalContext::error(const isc::eval::location& loc, const std::string& what) { + isc_throw(EvalParseError, loc << ": " << what); +} + +void +EvalContext::error (const std::string& what) { + isc_throw(EvalParseError, what); +} + +uint16_t +EvalContext::convertOptionCode(const std::string& option_code, + const isc::eval::location& loc) { + int n = 0; + try { + n = boost::lexical_cast(option_code); + } catch (const boost::bad_lexical_cast &) { + // This can't happen... + error(loc, "Option code has invalid value in " + option_code); + } + if (option_universe_ == Option::V6) { + if (n < 0 || n > 65535) { + error(loc, "Option code has invalid value in " + + option_code + ". Allowed range: 0..65535"); + } + } else { + if (n < 0 || n > 255) { + error(loc, "Option code has invalid value in " + + option_code + ". Allowed range: 0..255"); + } + } + return (static_cast(n)); +} + +uint16_t +EvalContext::convertOptionName(const std::string& option_name, + const isc::eval::location& loc) { + const std::string global_space = (option_universe_ == Option::V4) ? + DHCP4_OPTION_SPACE : DHCP6_OPTION_SPACE; + + OptionDefinitionPtr option_def = LibDHCP::getOptionDef(global_space, + option_name); + if (!option_def) { + option_def = LibDHCP::getRuntimeOptionDef(global_space, option_name); + } + + if (!option_def) { + option_def = LibDHCP::getLastResortOptionDef(global_space, option_name); + } + + if (!option_def) { + error(loc, "option '" + option_name + "' is not defined"); + } + + return (option_def->getCode()); +} + +int8_t +EvalContext::convertNestLevelNumber(const std::string& nest_level, + const isc::eval::location& loc) { + int8_t n = convertInt8(nest_level, loc); + if (option_universe_ == Option::V6) { + if ((n < - HOP_COUNT_LIMIT) || (n >= HOP_COUNT_LIMIT)) { + error(loc, "Nest level has invalid value in " + + nest_level + ". Allowed range: -32..31"); + } + } else { + error(loc, "Nest level invalid for DHCPv4 packets"); + } + + return (n); +} + +uint8_t +EvalContext::convertUint8(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid integer value in " + number); + } + if (n < 0 || n > std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: 0..255"); + } + + return (static_cast(n)); +} + +int8_t +EvalContext::convertInt8(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid integer value in " + number); + } + if (n < std::numeric_limits::min() || + n > std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: -128..127"); + } + + return (static_cast(n)); +} + +uint16_t +EvalContext::convertUint16(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n < 0 || n > std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: 0..65535"); + } + + return (static_cast(n)); +} + +int16_t +EvalContext::convertInt16(const std::string& number, + const isc::eval::location& loc) { + uint64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n > std::numeric_limits::max() || + n < std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: -32768..32767"); + } + + return (static_cast(n)); +} + +uint32_t +EvalContext::convertUint32(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n < 0 || n > std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: 0..4294967295"); + } + + return (static_cast(n)); +} + +int32_t +EvalContext::convertInt32(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n > std::numeric_limits::max() || + n < std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: -2147483648..2147483647"); + } + + return (static_cast(n)); +} + +std::string +EvalContext::fromUint32(const uint32_t integer) { + std::string tmp(4, 0); + tmp[0] = (integer >> 24) & 0xff; + tmp[1] = (integer >> 16) & 0xff; + tmp[2] = (integer >> 8) & 0xff; + tmp[3] = integer & 0xff; + + return (tmp); +} + +std::string +EvalContext::fromUint16(const uint16_t integer) { + std::string tmp(2, 0); + tmp[0] = (integer >> 8) & 0xff; + tmp[1] = integer & 0xff; + + return (tmp); +} + +bool +EvalContext::isClientClassDefined(const ClientClass& client_class) { + return (check_defined_(client_class)); +} + +void +EvalContext::fatal(const std::string& what) { + isc_throw(Unexpected, what); +} -- cgit v1.2.3