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>
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 
32 bool
34  return (true);
35 }
36 
37 bool
38 EvalContext::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 (...) {
49  scanStringEnd();
50  throw;
51  }
52  scanStringEnd();
53  return (res == 0);
54 }
55 
56 void
57 EvalContext::error(const isc::eval::location& loc, const std::string& what)
58 {
59  isc_throw(EvalParseError, loc << ": " << what);
60 }
61 
62 void
63 EvalContext::error (const std::string& what)
64 {
66 }
67 
68 uint16_t
69 EvalContext::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 
93 uint16_t
94 EvalContext::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 
117 int8_t
118 EvalContext::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 
134 uint8_t
135 EvalContext::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 
152 int8_t
153 EvalContext::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 
171 uint32_t
172 EvalContext::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 
189 std::string
190 EvalContext::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 
200 bool
202  return (check_defined_(client_class));
203 }
204 
205 void
206 EvalContext::fatal (const std::string& what)
207 {
208  isc_throw(Unexpected, what);
209 }
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition: exceptions/exceptions.h:153
option_space.h
isc::dhcp::OptionDefinitionPtr
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
Definition: option_definition.h:51
isc::eval::EvalContext::scanStringBegin
void scanStringBegin(ParserType type)
Method called before scanning starts on a string.
libdhcp++.h
isc::eval::EvalContext::CheckDefined
std::function< bool(const ClientClass &)> CheckDefined
Type of the check defined function.
Definition: eval_context.h:45
isc::eval::EvalContext::convertUint8
static uint8_t convertUint8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 8bit integer.
Definition: eval_context.cc:135
isc::eval::EvalContext::convertOptionCode
uint16_t convertOptionCode(const std::string &option_code, const isc::eval::location &loc)
Option code conversion.
Definition: eval_context.cc:69
isc::eval::EvalContext::convertUint32
static uint32_t convertUint32(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to unsigned 32bit integer.
Definition: eval_context.cc:172
isc::eval::EvalParser::set_debug_level
void set_debug_level(debug_level_type l)
Set the current debugging level.
Definition: parser.cc:590
DHCP6_OPTION_SPACE
#define DHCP6_OPTION_SPACE
Definition: option_space.h:17
isc::eval::EvalParser::parse
virtual int parse()
Parse.
Definition: parser.cc:625
isc::eval::EvalParseError
Evaluation error exception raised when trying to parse an exceptions.
Definition: eval_context.h:26
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
HOP_COUNT_LIMIT
#define HOP_COUNT_LIMIT
Definition: dhcp6.h:336
DHCP4_OPTION_SPACE
#define DHCP4_OPTION_SPACE
Definition: option_space.h:16
isc::eval::EvalContext::parseString
bool parseString(const std::string &str, ParserType type=PARSER_BOOL)
Run the parser on the string specified.
Definition: eval_context.cc:38
isc::eval::EvalParser
A Bison parser.
Definition: parser.h:495
eval_context.h
option_definition.h
isc::eval::EvalContext::fromUint32
static std::string fromUint32(const uint32_t integer)
Converts integer to string representation.
Definition: eval_context.cc:190
dhcp6.h
isc::eval::EvalContext::convertInt8
static int8_t convertInt8(const std::string &number, const isc::eval::location &loc)
Attempts to convert string to signed 8bit integer.
Definition: eval_context.cc:153
isc::eval::EvalContext::scanStringEnd
void scanStringEnd()
Method called after the last tokens are scanned from a string.
isc::eval::EvalContext::error
static void error(const isc::eval::location &loc, const std::string &what)
Error handler.
Definition: eval_context.cc:57
isc::eval::EvalContext::string_
std::string string_
The string being parsed.
Definition: eval_context.h:90
isc::eval::EvalContext::isClientClassDefined
bool isClientClassDefined(const ClientClass &client_class)
Check if a client class is already defined.
Definition: eval_context.cc:201
isc::eval::EvalContext::ParserType
ParserType
Specifies what type of expression the parser is expected to see.
Definition: eval_context.h:39
parser.h
isc::dhcp::ClientClass
std::string ClientClass
Defines a single class name.
Definition: classify.h:37
isc::eval::EvalContext::convertNestLevelNumber
int8_t convertNestLevelNumber(const std::string &nest_level, const isc::eval::location &loc)
Nest level conversion.
Definition: eval_context.cc:118
isc::eval::EvalContext::convertOptionName
uint16_t convertOptionName(const std::string &option_name, const isc::eval::location &loc)
Option name conversion.
Definition: eval_context.cc:94
exceptions.h
isc::eval::EvalContext::fatal
static void fatal(const std::string &what)
Fatal error handler.
Definition: eval_context.cc:206
isc::dhcp::Option::Universe
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
isc::eval::EvalContext::acceptAll
static bool acceptAll(const ClientClass &client_class)
Accept all client class names.
Definition: eval_context.cc:33
option.h
isc::eval::EvalContext::file_
std::string file_
The name of the file being parsed.
Definition: eval_context.h:87
isc::eval::EvalContext::~EvalContext
virtual ~EvalContext()
destructor
Definition: eval_context.cc:28