Kea 1.5.0
cfg_option_def.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2015,2017 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#include <dhcp/libdhcp++.h>
11#include <dhcp/option_space.h>
13#include <sstream>
14
15using namespace isc::data;
16
17namespace isc {
18namespace dhcp {
19
20void
22 // Remove any existing option definitions from the destination.
23 new_config.option_definitions_.clearItems();
24 const std::list<std::string>& names =
25 option_definitions_.getOptionSpaceNames();
26 for (std::list<std::string>::const_iterator name = names.begin();
27 name != names.end(); ++name) {
28 OptionDefContainerPtr defs = getAll(*name);
29 for (OptionDefContainer::const_iterator def = defs->begin();
30 def != defs->end(); ++def) {
31 OptionDefinitionPtr new_def =
33 new_config.add(new_def, *name);
34 }
35 }
36}
37
38bool
40 // Get our option space names.
41 const std::list<std::string>& names = option_definitions_.getOptionSpaceNames();
42 // Get option space names held by the other object.
43 const std::list<std::string>&
44 other_names = other.option_definitions_.getOptionSpaceNames();
45 // Compare that sizes are the same. If they hold different number of
46 // option space names the objects are not equal.
47 if (names.size() != other_names.size()) {
48 return (false);
49 }
50 // Iterate over all option space names and get the definitions for each
51 // of them.
52 for (std::list<std::string>::const_iterator name = names.begin();
53 name != names.end(); ++name) {
54 // Get all definitions.
55 OptionDefContainerPtr defs = getAll(*name);
56 OptionDefContainerPtr other_defs = other.getAll(*name);
57 // Compare sizes. If they hold different number of definitions,
58 // they are unequal.
59 if (defs->size() != defs->size()) {
60 return (false);
61 }
62 // For each option definition, try to find one in the other object.
63 for (OptionDefContainer::const_iterator def = defs->begin();
64 def != defs->end(); ++def) {
66 other_def = other.get(*name, (*def)->getCode());
67 // Actually compare them.
68 if (!other_def || (*other_def != **def)) {
69 return (false);
70 }
71 }
72 }
73
74 // All checks passed.
75 return (true);
76}
77
78void
80 const std::string& option_space) {
81 if (!OptionSpace::validateName(option_space)) {
82 isc_throw(BadValue, "invalid option space name '"
83 << option_space << "'");
84
85 // Option definition being added must be a valid pointer.
86 } else if (!def) {
88 "option definition must not be NULL");
89 // Must not duplicate an option definition.
90 } else if (get(option_space, def->getCode())) {
91 isc_throw(DuplicateOptionDefinition, "option definition with code '"
92 << def->getCode() << "' already exists in option"
93 " space '" << option_space << "'");
94
95 // Must not override standard option definition.
96 } else if (LibDHCP::getOptionDef(option_space, def->getCode())) {
97 isc_throw(BadValue, "unable to override definition of option '"
98 << def->getCode() << "' in standard option space '"
99 << option_space << "'");
100 }
101 // Add the definition.
102 option_definitions_.addItem(def, option_space);
103}
104
106CfgOptionDef::getAll(const std::string& option_space) const {
108 return (option_definitions_.getItems(option_space));
109}
110
112CfgOptionDef::get(const std::string& option_space,
113 const uint16_t option_code) const {
114 // Get the pointer to collection of the option definitions that belong
115 // to the particular option space.
116 OptionDefContainerPtr defs = getAll(option_space);
117 // If there are any option definitions for this option space, get the
118 // one that has the specified option code.
119 if (defs && !defs->empty()) {
120 const OptionDefContainerTypeIndex& idx = defs->get<1>();
121 const OptionDefContainerTypeRange& range = idx.equal_range(option_code);
122 // If there is more than one definition matching the option code,
123 // return the first one. In fact, it shouldn't happen that we have
124 // more than one because we check for duplicates when we add them.
125 if (std::distance(range.first, range.second) > 0) {
126 return (*range.first);
127 }
128 }
129 // Nothing found. Return NULL pointer.
130 return (OptionDefinitionPtr());
131}
132
134CfgOptionDef::get(const std::string& option_space,
135 const std::string& option_name) const {
136 // Get the pointer to collection of the option definitions that belong
137 // to the particular option space.
138 OptionDefContainerPtr defs = getAll(option_space);
139 // If there are any option definitions for this option space, get the
140 // one that has the specified option name.
141 if (defs && !defs->empty()) {
142 const OptionDefContainerNameIndex& idx = defs->get<2>();
143 const OptionDefContainerNameRange& range = idx.equal_range(option_name);
144 // If there is more than one definition matching the option name,
145 // return the first one. In fact, it shouldn't happen that we have
146 // more than one because we check for duplicates when we add them.
147 if (std::distance(range.first, range.second) > 0) {
148 return (*range.first);
149 }
150 }
151 // Nothing found. Return NULL pointer.
152 return (OptionDefinitionPtr());
153}
154
157 // option-defs value is a list of maps
159 // Iterate through the container by names and definitions
160 const std::list<std::string>& names =
161 option_definitions_.getOptionSpaceNames();
162 for (std::list<std::string>::const_iterator name = names.begin();
163 name != names.end(); ++name) {
164 OptionDefContainerPtr defs = getAll(*name);
165 for (OptionDefContainer::const_iterator def = defs->begin();
166 def != defs->end(); ++def) {
167 // Get and fill the map for this definition
169 // Set user context
170 (*def)->contextToElement(map);
171 // Set space from parent iterator
172 map->set("space", Element::create(*name));
173 // Set required items: name, code and type
174 map->set("name", Element::create((*def)->getName()));
175 map->set("code", Element::create((*def)->getCode()));
176 std::string data_type =
177 OptionDataTypeUtil::getDataTypeName((*def)->getType());
178 map->set("type", Element::create(data_type));
179 // Set the array type
180 bool array_type = (*def)->getArrayType();
181 map->set("array", Element::create(array_type));
182 // Set the encapsulate space
183 std::string encapsulates = (*def)->getEncapsulatedSpace();
184 map->set("encapsulate", Element::create(encapsulates));
185 // Set the record field types
187 (*def)->getRecordFields();
188 if (!fields.empty()) {
189 std::ostringstream oss;
190 for (OptionDefinition::RecordFieldsCollection::const_iterator
191 field = fields.begin();
192 field != fields.end(); ++field) {
193 if (field != fields.begin()) {
194 oss << ", ";
195 }
197 }
198 map->set("record-types", Element::create(oss.str()));
199 } else {
200 map->set("record-types", Element::create(std::string()));
201 }
202 // Push on the list
203 result->add(map);
204 }
205 }
206 return (result);
207}
208
209} // end of namespace isc::dhcp
210} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:223
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:268
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:263
Represents option definitions used by the DHCP server.
void add(const OptionDefinitionPtr &def, const std::string &option_space)
Add new option definition.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
OptionDefContainerPtr getAll(const std::string &option_space) const
Return option definitions for particular option space.
bool equals(const CfgOptionDef &other) const
Check if configuration is equal to other configuration.
OptionDefinitionPtr get(const std::string &option_space, const uint16_t option_code) const
Return option definition for a particular option space and code.
void copyTo(CfgOptionDef &new_config) const
Copies this configuration to a new configuration.
Exception to be thrown when the particular option definition duplicates existing option definition.
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
Exception to be thrown when option definition is invalid.
static const std::string & getDataTypeName(const OptionDataType data_type)
Return option data type name from the data type enumerator.
Base class representing a DHCP option definition.
std::vector< OptionDataType > RecordFieldsCollection
List of fields within the record.
void addItem(const ItemType &item, const Selector &option_space)
Adds a new item to the option_space.
void clearItems()
Remove all items from the container.
std::list< Selector > getOptionSpaceNames() const
Get a list of existing option spaces.
ItemsContainerPtr getItems(const Selector &option_space) const
Get all items for the particular option space.
static bool validateName(const std::string &name)
Checks that the provided option space name is valid.
Definition: option_space.cc:26
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:22
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
std::pair< OptionDefContainerNameIndex::const_iterator, OptionDefContainerNameIndex::const_iterator > OptionDefContainerNameRange
Pair of iterators to represent the range of options definitions having the same option name.
OptionDefContainer::nth_index< 2 >::type OptionDefContainerNameIndex
Type of the index #2 - option name.
std::pair< OptionDefContainerTypeIndex::const_iterator, OptionDefContainerTypeIndex::const_iterator > OptionDefContainerTypeRange
Pair of iterators to represent the range of options definitions having the same option type value.
OptionDefContainer::nth_index< 1 >::type OptionDefContainerTypeIndex
Type of the index #1 - option type.
boost::shared_ptr< OptionDefContainer > OptionDefContainerPtr
Pointer to an option definition container.
Defines the logger used by the top-level component of kea-dhcp-ddns.