Kea  1.9.9-git
eval_context.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2021 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>
11 #include <dhcp/option_definition.h>
12 #include <dhcp/libdhcp++.h>
13 #include <dhcp/option_space.h>
14 #include <eval/eval_context.h>
15 #include <eval/parser.h>
16 #include <exceptions/exceptions.h>
17 #include <boost/lexical_cast.hpp>
18 #include <fstream>
19 #include <limits>
20 
21 EvalContext::EvalContext(const Option::Universe& option_universe,
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 bool
33  return (true);
34 }
35 
36 bool
37 EvalContext::parseString(const std::string& str, ParserType type) {
38  file_ = "<string>";
39  string_ = str;
40  scanStringBegin(type);
41  int res = -1;
42  try {
43  isc::eval::EvalParser parser(*this);
44  parser.set_debug_level(trace_parsing_);
45  res = parser.parse();
46  } catch (...) {
47  scanStringEnd();
48  throw;
49  }
50  scanStringEnd();
51  return (res == 0);
52 }
53 
54 void
55 EvalContext::error(const isc::eval::location& loc, const std::string& what) {
56  isc_throw(EvalParseError, loc << ": " << what);
57 }
58 
59 void
60 EvalContext::error (const std::string& what) {
62 }
63 
64 uint16_t
65 EvalContext::convertOptionCode(const std::string& option_code,
66  const isc::eval::location& loc) {
67  int n = 0;
68  try {
69  n = boost::lexical_cast<int>(option_code);
70  } catch (const boost::bad_lexical_cast &) {
71  // This can't happen...
72  error(loc, "Option code has invalid value in " + option_code);
73  }
74  if (option_universe_ == Option::V6) {
75  if (n < 0 || n > 65535) {
76  error(loc, "Option code has invalid value in "
77  + option_code + ". Allowed range: 0..65535");
78  }
79  } else {
80  if (n < 0 || n > 255) {
81  error(loc, "Option code has invalid value in "
82  + option_code + ". Allowed range: 0..255");
83  }
84  }
85  return (static_cast<uint16_t>(n));
86 }
87 
88 uint16_t
89 EvalContext::convertOptionName(const std::string& option_name,
90  const isc::eval::location& loc) {
91  const std::string global_space = (option_universe_ == Option::V4) ?
93 
94  OptionDefinitionPtr option_def = LibDHCP::getOptionDef(global_space,
95  option_name);
96  if (!option_def) {
97  option_def = LibDHCP::getRuntimeOptionDef(global_space, option_name);
98  }
99 
100  if (!option_def) {
101  option_def = LibDHCP::getLastResortOptionDef(global_space, option_name);
102  }
103 
104  if (!option_def) {
105  error(loc, "option '" + option_name + "' is not defined");
106  }
107 
108  return (option_def->getCode());
109 }
110 
111 int8_t
112 EvalContext::convertNestLevelNumber(const std::string& nest_level,
113  const isc::eval::location& loc) {
114  int8_t n = convertInt8(nest_level, loc);
115  if (option_universe_ == Option::V6) {
116  if ((n < - HOP_COUNT_LIMIT) || (n >= HOP_COUNT_LIMIT)) {
117  error(loc, "Nest level has invalid value in "
118  + nest_level + ". Allowed range: -32..31");
119  }
120  } else {
121  error(loc, "Nest level invalid for DHCPv4 packets");
122  }
123 
124  return (n);
125 }
126 
127 uint8_t
128 EvalContext::convertUint8(const std::string& number,
129  const isc::eval::location& loc) {
130  int64_t n = 0;
131  try {
132  n = boost::lexical_cast<int64_t>(number);
133  } catch (const boost::bad_lexical_cast &) {
134  error(loc, "Invalid integer value in " + number);
135  }
136  if (n < 0 || n > std::numeric_limits<uint8_t>::max()) {
137  error(loc, "Invalid value in "
138  + number + ". Allowed range: 0..255");
139  }
140 
141  return (static_cast<uint8_t>(n));
142 }
143 
144 int8_t
145 EvalContext::convertInt8(const std::string& number,
146  const isc::eval::location& loc) {
147  int64_t n = 0;
148  try {
149  n = boost::lexical_cast<int64_t>(number);
150  } catch (const boost::bad_lexical_cast &) {
151  error(loc, "Invalid integer value in " + number);
152  }
153  if (n < std::numeric_limits<int8_t>::min() ||
154  n > std::numeric_limits<int8_t>::max()) {
155  error(loc, "Invalid value in "
156  + number + ". Allowed range: -128..127");
157  }
158 
159  return (static_cast<int8_t>(n));
160 }
161 
162 uint16_t
163 EvalContext::convertUint16(const std::string& number,
164  const isc::eval::location& loc) {
165  int64_t n = 0;
166  try {
167  n = boost::lexical_cast<int64_t>(number);
168  } catch (const boost::bad_lexical_cast &) {
169  error(loc, "Invalid value in " + number);
170  }
171  if (n < 0 || n > std::numeric_limits<uint16_t>::max()) {
172  error(loc, "Invalid value in "
173  + number + ". Allowed range: 0..65535");
174  }
175 
176  return (static_cast<uint16_t>(n));
177 }
178 
179 int16_t
180 EvalContext::convertInt16(const std::string& number,
181  const isc::eval::location& loc) {
182  uint64_t n = 0;
183  try {
184  n = boost::lexical_cast<int64_t>(number);
185  } catch (const boost::bad_lexical_cast &) {
186  error(loc, "Invalid value in " + number);
187  }
188  if (n > std::numeric_limits<int16_t>::max() ||
189  n < std::numeric_limits<int16_t>::max()) {
190  error(loc, "Invalid value in "
191  + number + ". Allowed range: -32768..32767");
192  }
193 
194  return (static_cast<int16_t>(n));
195 }
196 
197 uint32_t
198 EvalContext::convertUint32(const std::string& number,
199  const isc::eval::location& loc) {
200  int64_t n = 0;
201  try {
202  n = boost::lexical_cast<int64_t>(number);
203  } catch (const boost::bad_lexical_cast &) {
204  error(loc, "Invalid value in " + number);
205  }
206  if (n < 0 || n > std::numeric_limits<uint32_t>::max()) {
207  error(loc, "Invalid value in "
208  + number + ". Allowed range: 0..4294967295");
209  }
210 
211  return (static_cast<uint32_t>(n));
212 }
213 
214 int32_t
215 EvalContext::convertInt32(const std::string& number,
216  const isc::eval::location& loc) {
217  int64_t n = 0;
218  try {
219  n = boost::lexical_cast<int64_t>(number);
220  } catch (const boost::bad_lexical_cast &) {
221  error(loc, "Invalid value in " + number);
222  }
223  if (n > std::numeric_limits<int32_t>::max() ||
224  n < std::numeric_limits<int32_t>::max()) {
225  error(loc, "Invalid value in "
226  + number + ". Allowed range: -2147483648..2147483647");
227  }
228 
229  return (static_cast<int32_t>(n));
230 }
231 
232 std::string
233 EvalContext::fromUint32(const uint32_t integer) {
234  std::string tmp(4, 0);
235  tmp[0] = (integer >> 24) & 0xff;
236  tmp[1] = (integer >> 16) & 0xff;
237  tmp[2] = (integer >> 8) & 0xff;
238  tmp[3] = integer & 0xff;
239 
240  return (tmp);
241 }
242 
243 std::string
244 EvalContext::fromUint16(const uint16_t integer) {
245  std::string tmp(2, 0);
246  tmp[0] = (integer >> 8) & 0xff;
247  tmp[1] = integer & 0xff;
248 
249  return (tmp);
250 }
251 
252 bool
254  return (check_defined_(client_class));
255 }
256 
257 void
258 EvalContext::fatal(const std::string& what) {
259  isc_throw(Unexpected, what);
260 }
void set_debug_level(debug_level_type l)
Set the current debugging level.
Definition: parser.cc:604
static uint32_t convertUint32(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 32bit integer.
Evaluation error exception raised when trying to parse an exceptions.
Definition: eval_context.h:26
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:82
static uint16_t convertUint16(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 16bit integer.
static void error(const isc::eval::location &loc, const std::string &what)
Error handler.
Definition: eval_context.cc:55
void scanStringBegin(ParserType type)
Method called before scanning starts on a string.
static int16_t convertInt16(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to signed 16bit integer.
std::string string_
The string being parsed.
Definition: eval_context.h:89
Define the isc::eval::parser class.
static int32_t convertInt32(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to signed 32bit integer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown when an unexpected error condition occurs.
std::string file_
The name of the file being parsed.
Definition: eval_context.h:86
static std::string fromUint32(const uint32_t integer)
Converts unsigned 32bit integer to string representation.
static uint8_t convertUint8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 8bit integer.
uint16_t convertOptionName(const std::string &option_name, const isc::eval::location &loc)
Option name conversion.
Definition: eval_context.cc:89
uint16_t convertOptionCode(const std::string &option_code, const isc::eval::location &loc)
Option code conversion.
Definition: eval_context.cc:65
virtual int parse()
Parse.
Definition: parser.cc:639
static void fatal(const std::string &what)
Fatal error handler.
A Bison parser.
Definition: parser.h:208
#define HOP_COUNT_LIMIT
Definition: dhcp6.h:327
void scanStringEnd()
Method called after the last tokens are scanned from a string.
static std::string fromUint16(const uint16_t integer)
Converts unsigned 16bit integer to string representation.
#define DHCP6_OPTION_SPACE
#define DHCP4_OPTION_SPACE
global std option spaces
ParserType
Specifies what type of expression the parser is expected to see.
Definition: eval_context.h:38
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
int8_t convertNestLevelNumber(const std::string &nest_level, const isc::eval::location &loc)
Nest level conversion.
std::string ClientClass
Defines a single class name.
Definition: classify.h:37
static int8_t convertInt8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to signed 8bit integer.
std::function< bool(const ClientClass &)> CheckDefined
Type of the check defined function.
Definition: eval_context.h:44
virtual ~EvalContext()
destructor
Definition: eval_context.cc:28
bool isClientClassDefined(const ClientClass &client_class)
Check if a client class is already defined.
bool parseString(const std::string &str, ParserType type=PARSER_BOOL)
Run the parser on the string specified.
Definition: eval_context.cc:37
static bool acceptAll(const ClientClass &client_class)
Accept all client class names.
Definition: eval_context.cc:32