Kea 1.5.0
eval_context.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcp/dhcp6.h>
10#include <dhcp/option.h>
12#include <dhcp/libdhcp++.h>
13#include <dhcp/option_space.h>
14#include <eval/eval_context.h>
15#include <eval/parser.h>
17#include <boost/lexical_cast.hpp>
18#include <fstream>
19#include <limits>
20
22 CheckDefined check_defined)
23 : trace_scanning_(false), trace_parsing_(false),
24 option_universe_(option_universe), check_defined_(check_defined)
25{
26}
27
29{
30}
31
32bool
34 return (true);
35}
36
37bool
38EvalContext::parseString(const std::string& str, ParserType type)
39{
40 file_ = "<string>";
41 string_ = str;
42 scanStringBegin(type);
43 int res = -1;
44 try {
45 isc::eval::EvalParser parser(*this);
46 parser.set_debug_level(trace_parsing_);
47 res = parser.parse();
48 } catch (...) {
50 throw;
51 }
53 return (res == 0);
54}
55
56void
57EvalContext::error(const isc::eval::location& loc, const std::string& what)
58{
59 isc_throw(EvalParseError, loc << ": " << what);
60}
61
62void
63EvalContext::error (const std::string& what)
64{
66}
67
68uint16_t
69EvalContext::convertOptionCode(const std::string& option_code,
70 const isc::eval::location& loc)
71{
72 int n = 0;
73 try {
74 n = boost::lexical_cast<int>(option_code);
75 } catch (const boost::bad_lexical_cast &) {
76 // This can't happen...
77 error(loc, "Option code has invalid value in " + option_code);
78 }
79 if (option_universe_ == Option::V6) {
80 if (n < 0 || n > 65535) {
81 error(loc, "Option code has invalid value in "
82 + option_code + ". Allowed range: 0..65535");
83 }
84 } else {
85 if (n < 0 || n > 255) {
86 error(loc, "Option code has invalid value in "
87 + option_code + ". Allowed range: 0..255");
88 }
89 }
90 return (static_cast<uint16_t>(n));
91}
92
93uint16_t
94EvalContext::convertOptionName(const std::string& option_name,
95 const isc::eval::location& loc)
96{
97 const std::string global_space = (option_universe_ == Option::V4) ?
99
100 OptionDefinitionPtr option_def = LibDHCP::getOptionDef(global_space,
101 option_name);
102 if (!option_def) {
103 option_def = LibDHCP::getRuntimeOptionDef(global_space, option_name);
104 }
105
106 if (!option_def) {
107 option_def = LibDHCP::getLastResortOptionDef(global_space, option_name);
108 }
109
110 if (!option_def) {
111 error(loc, "option '" + option_name + "' is not defined");
112 }
113
114 return (option_def->getCode());
115}
116
117int8_t
118EvalContext::convertNestLevelNumber(const std::string& nest_level,
119 const isc::eval::location& loc)
120{
121 int8_t n = convertInt8(nest_level, loc);
122 if (option_universe_ == Option::V6) {
123 if ((n < - HOP_COUNT_LIMIT) || (n >= HOP_COUNT_LIMIT)) {
124 error(loc, "Nest level has invalid value in "
125 + nest_level + ". Allowed range: -32..31");
126 }
127 } else {
128 error(loc, "Nest level invalid for DHCPv4 packets");
129 }
130
131 return (n);
132}
133
134uint8_t
135EvalContext::convertUint8(const std::string& number,
136 const isc::eval::location& loc)
137{
138 int n = 0;
139 try {
140 n = boost::lexical_cast<int>(number);
141 } catch (const boost::bad_lexical_cast &) {
142 error(loc, "Invalid integer value in " + number);
143 }
144 if (n < 0 || n > std::numeric_limits<uint8_t>::max()) {
145 error(loc, "Invalid value in "
146 + number + ". Allowed range: 0..255");
147 }
148
149 return (static_cast<uint8_t>(n));
150}
151
152int8_t
153EvalContext::convertInt8(const std::string& number,
154 const isc::eval::location& loc)
155{
156 int n = 0;
157 try {
158 n = boost::lexical_cast<int>(number);
159 } catch (const boost::bad_lexical_cast &) {
160 error(loc, "Invalid integer value in " + number);
161 }
162 if (n < std::numeric_limits<int8_t>::min() ||
163 n > std::numeric_limits<int8_t>::max()) {
164 error(loc, "Invalid value in "
165 + number + ". Allowed range: 0..255");
166 }
167
168 return (static_cast<uint8_t>(n));
169}
170
171uint32_t
172EvalContext::convertUint32(const std::string& number,
173 const isc::eval::location& loc)
174{
175 uint64_t n = 0;
176 try {
177 n = boost::lexical_cast<uint64_t>(number);
178 } catch (const boost::bad_lexical_cast &) {
179 error(loc, "Invalid value in " + number);
180 }
181 if (n > std::numeric_limits<uint32_t>::max()) {
182 error(loc, "Invalid value in "
183 + number + ". Allowed range: 0..4294967295");
184 }
185
186 return (static_cast<uint32_t>(n));
187}
188
189std::string
190EvalContext::fromUint32(const uint32_t integer) {
191 std::string tmp(4, 0);
192 tmp[0] = (integer >> 24) & 0xff;
193 tmp[1] = (integer >> 16) & 0xff;
194 tmp[2] = (integer >> 8) & 0xff;
195 tmp[3] = integer & 0xff;
196
197 return (tmp);
198}
199
200bool
202 return (check_defined_(client_class));
203}
204
205void
206EvalContext::fatal (const std::string& what)
207{
208 isc_throw(Unexpected, what);
209}
A generic exception that is thrown when an unexpected error condition occurs.
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
Definition: libdhcp++.cc:144
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
Definition: libdhcp++.cc:205
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
Definition: libdhcp++.cc:265
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
std::function< bool(const ClientClass &)> CheckDefined
Type of the check defined function.
Definition: eval_context.h:45
bool parseString(const std::string &str, ParserType type=PARSER_BOOL)
Run the parser on the string specified.
Definition: eval_context.cc:38
void scanStringEnd()
Method called after the last tokens are scanned from a string.
ParserType
Specifies what type of expression the parser is expected to see.
Definition: eval_context.h:39
static std::string fromUint32(const uint32_t integer)
Converts integer to string representation.
virtual ~EvalContext()
destructor
Definition: eval_context.cc:28
int8_t convertNestLevelNumber(const std::string &nest_level, const isc::eval::location &loc)
Nest level conversion.
uint16_t convertOptionCode(const std::string &option_code, const isc::eval::location &loc)
Option code conversion.
Definition: eval_context.cc:69
uint16_t convertOptionName(const std::string &option_name, const isc::eval::location &loc)
Option name conversion.
Definition: eval_context.cc:94
static bool acceptAll(const ClientClass &client_class)
Accept all client class names.
Definition: eval_context.cc:33
void scanStringBegin(ParserType type)
Method called before scanning starts on a string.
static uint32_t convertUint32(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 32bit integer.
bool isClientClassDefined(const ClientClass &client_class)
Check if a client class is already defined.
std::string file_
The name of the file being parsed.
Definition: eval_context.h:87
std::string string_
The string being parsed.
Definition: eval_context.h:90
static uint8_t convertUint8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 8bit integer.
static int8_t convertInt8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to signed 8bit integer.
static void fatal(const std::string &what)
Fatal error handler.
static void error(const isc::eval::location &loc, const std::string &what)
Error handler.
Definition: eval_context.cc:57
EvalContext(const Option::Universe &option_universe, CheckDefined check_defined=acceptAll)
Default constructor.
Definition: eval_context.cc:21
Evaluation error exception raised when trying to parse an exceptions.
Definition: eval_context.h:26
A Bison parser.
Definition: parser.h:495
virtual int parse()
Parse.
Definition: parser.cc:625
#define HOP_COUNT_LIMIT
Definition: dhcp6.h:336
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::string ClientClass
Defines a single class name.
Definition: classify.h:37
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
#define DHCP4_OPTION_SPACE
Definition: option_space.h:16
#define DHCP6_OPTION_SPACE
Definition: option_space.h:17
Define the isc::eval::parser class.