dhcp_parsers.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. // Copyright (C) 2013-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. #ifndef DHCP_PARSERS_H
  7. #define DHCP_PARSERS_H
  8. #include <asiolink/io_address.h>
  9. #include <cc/data.h>
  10. #include <dhcp/option_definition.h>
  11. #include <dhcp/option_space_container.h>
  12. #include <dhcpsrv/d2_client_cfg.h>
  13. #include <dhcpsrv/cfg_iface.h>
  14. #include <dhcpsrv/cfg_option.h>
  15. #include <dhcpsrv/subnet.h>
  16. #include <dhcpsrv/cfg_option_def.h>
  17. #include <dhcpsrv/cfg_mac_source.h>
  18. #include <dhcpsrv/srv_config.h>
  19. #include <dhcpsrv/parsers/dhcp_config_parser.h>
  20. #include <cc/simple_parser.h>
  21. #include <exceptions/exceptions.h>
  22. #include <util/optional_value.h>
  23. #include <boost/shared_ptr.hpp>
  24. #include <stdint.h>
  25. #include <string>
  26. #include <vector>
  27. namespace isc {
  28. namespace dhcp {
  29. /// Collection of containers holding option spaces. Each container within
  30. /// a particular option space holds so-called option descriptors.
  31. typedef OptionSpaceContainer<OptionContainer, OptionDescriptor,
  32. std::string> OptionStorage;
  33. /// @brief Shared pointer to option storage.
  34. typedef boost::shared_ptr<OptionStorage> OptionStoragePtr;
  35. /// @brief A template class that stores named elements of a given data type.
  36. ///
  37. /// This template class is provides data value storage for configuration
  38. /// parameters of a given data type. The values are stored by parameter name
  39. /// and as instances of type "ValueType". Each value held in the storage has
  40. /// a corresponding position within a configuration string (file) specified
  41. /// as a: file name, line number and position within the line. The position
  42. /// information is used for logging when the particular configuration value
  43. /// causes a configuration error.
  44. ///
  45. /// @tparam ValueType is the data type of the elements to store.
  46. template<typename ValueType>
  47. class ValueStorage {
  48. public:
  49. /// @brief Stores the the parameter, its value and the position in the
  50. /// store.
  51. ///
  52. /// If the parameter does not exist in the store, then it will be added,
  53. /// otherwise its data value and the position will be updated with the
  54. /// given values.
  55. ///
  56. /// @param name is the name of the parameter to store.
  57. /// @param value is the data value to store.
  58. /// @param position is the position of the data element within a
  59. /// configuration string (file).
  60. void setParam(const std::string& name, const ValueType& value,
  61. const data::Element::Position& position) {
  62. values_[name] = value;
  63. positions_[name] = position;
  64. }
  65. /// @brief Returns the data value for the given parameter.
  66. ///
  67. /// Finds and returns the data value for the given parameter.
  68. /// @param name is the name of the parameter for which the data
  69. /// value is desired.
  70. ///
  71. /// @return The parameter's data value of type @c ValueType.
  72. /// @throw DhcpConfigError if the parameter is not found.
  73. ValueType getParam(const std::string& name) const {
  74. typename std::map<std::string, ValueType>::const_iterator param
  75. = values_.find(name);
  76. if (param == values_.end()) {
  77. isc_throw(DhcpConfigError, "Missing parameter '"
  78. << name << "'");
  79. }
  80. return (param->second);
  81. }
  82. /// @brief Returns position of the data element in the configuration string.
  83. ///
  84. /// The returned object comprises file name, line number and the position
  85. /// within the particular line of the configuration string where the data
  86. /// element holding a particular value is located.
  87. ///
  88. /// @param name is the name of the parameter which position is desired.
  89. /// @param parent Pointer to a data element which position should be
  90. /// returned when position of the specified parameter is not found.
  91. ///
  92. /// @return Position of the data element or the position holding empty
  93. /// file name and two zeros if the position hasn't been specified for the
  94. /// particular value.
  95. const data::Element::Position&
  96. getPosition(const std::string& name, const data::ConstElementPtr parent =
  97. data::ConstElementPtr()) const {
  98. typename std::map<std::string, data::Element::Position>::const_iterator
  99. pos = positions_.find(name);
  100. if (pos == positions_.end()) {
  101. return (parent ? parent->getPosition() :
  102. data::Element::ZERO_POSITION());
  103. }
  104. return (pos->second);
  105. }
  106. /// @brief Returns the data value for an optional parameter.
  107. ///
  108. /// Finds and returns the data value for the given parameter or
  109. /// a supplied default value if it is not found.
  110. ///
  111. /// @param name is the name of the parameter for which the data
  112. /// value is desired.
  113. /// @param default_value value to use the default
  114. ///
  115. /// @return The parameter's data value of type @c ValueType.
  116. ValueType getOptionalParam(const std::string& name,
  117. const ValueType& default_value) const {
  118. typename std::map<std::string, ValueType>::const_iterator param
  119. = values_.find(name);
  120. if (param == values_.end()) {
  121. return (default_value);
  122. }
  123. return (param->second);
  124. }
  125. /// @brief Remove the parameter from the store.
  126. ///
  127. /// Deletes the entry for the given parameter from the store if it
  128. /// exists.
  129. ///
  130. /// @param name is the name of the parameter to delete.
  131. void delParam(const std::string& name) {
  132. values_.erase(name);
  133. positions_.erase(name);
  134. }
  135. /// @brief Deletes all of the entries from the store.
  136. ///
  137. void clear() {
  138. values_.clear();
  139. positions_.clear();
  140. }
  141. private:
  142. /// @brief An std::map of the data values, keyed by parameter names.
  143. std::map<std::string, ValueType> values_;
  144. /// @brief An std::map holding positions of the data elements in the
  145. /// configuration, which values are held in @c values_.
  146. ///
  147. /// The position is used for logging, when the particular value
  148. /// causes a configuration error.
  149. std::map<std::string, data::Element::Position> positions_;
  150. };
  151. /// @brief a collection of elements that store uint32 values
  152. typedef ValueStorage<uint32_t> Uint32Storage;
  153. typedef boost::shared_ptr<Uint32Storage> Uint32StoragePtr;
  154. /// @brief a collection of elements that store string values
  155. typedef ValueStorage<std::string> StringStorage;
  156. typedef boost::shared_ptr<StringStorage> StringStoragePtr;
  157. /// @brief Storage for parsed boolean values.
  158. typedef ValueStorage<bool> BooleanStorage;
  159. typedef boost::shared_ptr<BooleanStorage> BooleanStoragePtr;
  160. /// @brief Simple data-type parser template class
  161. ///
  162. /// This is the template class for simple data-type parsers. It supports
  163. /// parsing a configuration parameter with specific data-type for its
  164. /// possible values. It provides a common constructor, commit, and templated
  165. /// data storage. The "build" method implementation must be provided by a
  166. /// declaring type.
  167. /// @param ValueType is the data type of the configuration parameter value
  168. /// the parser should handle.
  169. template<typename ValueType>
  170. class ValueParser : public DhcpConfigParser {
  171. public:
  172. /// @brief Constructor.
  173. ///
  174. /// @param param_name name of the parameter.
  175. /// @param storage is a pointer to the storage container where the parsed
  176. /// value be stored upon commit.
  177. /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
  178. /// name is empty.
  179. /// @throw isc::dhcp::DhcpConfigError if storage is null.
  180. ValueParser(const std::string& param_name,
  181. boost::shared_ptr<ValueStorage<ValueType> > storage)
  182. : storage_(storage), param_name_(param_name), value_(), pos_() {
  183. // Empty parameter name is invalid.
  184. if (param_name_.empty()) {
  185. isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
  186. << "empty parameter name provided");
  187. }
  188. // Null storage is invalid.
  189. if (!storage_) {
  190. isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
  191. << "storage may not be NULL");
  192. }
  193. }
  194. /// @brief Parse a given element into a value of type @c ValueType
  195. ///
  196. /// @param value a value to be parsed.
  197. ///
  198. /// @throw isc::BadValue Typically the implementing type will throw
  199. /// a BadValue exception when given an invalid Element to parse.
  200. void build(isc::data::ConstElementPtr value);
  201. /// @brief Put a parsed value to the storage.
  202. void commit() {
  203. // If a given parameter already exists in the storage we override
  204. // its value. If it doesn't we insert a new element.
  205. storage_->setParam(param_name_, value_, pos_);
  206. }
  207. private:
  208. /// @brief Performs operations common for all specializations of the
  209. /// @c build function.
  210. ///
  211. /// This method should be called by all specializations of the @c build
  212. /// method.
  213. ///
  214. /// @param value a value being parsed.
  215. void buildCommon(isc::data::ConstElementPtr value) {
  216. // Remember position of the data element.
  217. pos_ = value->getPosition();
  218. }
  219. /// Pointer to the storage where committed value is stored.
  220. boost::shared_ptr<ValueStorage<ValueType> > storage_;
  221. /// Name of the parameter which value is parsed with this parser.
  222. std::string param_name_;
  223. /// Parsed value.
  224. ValueType value_;
  225. data::Element::Position pos_;
  226. };
  227. /// @brief typedefs for simple data type parsers
  228. typedef ValueParser<bool> BooleanParser;
  229. typedef ValueParser<uint32_t> Uint32Parser;
  230. typedef ValueParser<std::string> StringParser;
  231. /// @brief a dummy configuration parser
  232. ///
  233. /// It is a debugging parser. It does not configure anything,
  234. /// will accept any configuration and will just print it out
  235. /// on commit. Useful for debugging existing configurations and
  236. /// adding new ones.
  237. class DebugParser : public DhcpConfigParser {
  238. public:
  239. /// @brief Constructor
  240. ///
  241. /// See @ref DhcpConfigParser class for details.
  242. ///
  243. /// @param param_name name of the parsed parameter
  244. DebugParser(const std::string& param_name);
  245. /// @brief builds parameter value
  246. ///
  247. /// See @ref DhcpConfigParser class for details.
  248. ///
  249. /// @param new_config pointer to the new configuration
  250. virtual void build(isc::data::ConstElementPtr new_config);
  251. /// @brief pretends to apply the configuration
  252. ///
  253. /// This is a method required by base class. It pretends to apply the
  254. /// configuration, but in fact it only prints the parameter out.
  255. ///
  256. /// See @ref DhcpConfigParser class for details.
  257. virtual void commit();
  258. private:
  259. /// name of the parsed parameter
  260. std::string param_name_;
  261. /// pointer to the actual value of the parameter
  262. isc::data::ConstElementPtr value_;
  263. };
  264. /// @brief parser for MAC/hardware acquisition sources
  265. ///
  266. /// This parser handles Dhcp6/mac-sources entry.
  267. /// It contains a list of MAC/hardware acquisition source, i.e. methods how
  268. /// MAC address can possibly by obtained in DHCPv6. For a currently supported
  269. /// methods, see @ref isc::dhcp::Pkt::getMAC.
  270. class MACSourcesListConfigParser : public isc::data::SimpleParser {
  271. public:
  272. /// @brief parses parameters value
  273. ///
  274. /// Parses configuration entry (list of sources) and adds each element
  275. /// to the sources list.
  276. ///
  277. /// @param value pointer to the content of parsed values
  278. /// @param mac_sources parsed sources will be stored here
  279. void parse(CfgMACSource& mac_sources, isc::data::ConstElementPtr value);
  280. };
  281. /// @brief Parser for the control-socket structure
  282. ///
  283. /// It does not parse anything, simply stores the element in
  284. /// the staging config.
  285. class ControlSocketParser : public isc::data::SimpleParser {
  286. public:
  287. /// @brief "Parses" control-socket structure
  288. ///
  289. /// Since the SrvConfig structure takes the socket definition
  290. /// as ConstElementPtr, there's really nothing to parse here.
  291. /// It only does basic sanity checks and throws DhcpConfigError
  292. /// if the value is null or is not a map.
  293. ///
  294. /// @param srv_cfg parsed values will be stored here
  295. /// @param value pointer to the content of parsed values
  296. void parse(SrvConfig& srv_cfg, isc::data::ConstElementPtr value);
  297. };
  298. typedef std::pair<isc::dhcp::OptionDefinitionPtr, std::string> OptionDefinitionTuple;
  299. /// @brief Parser for a single option definition.
  300. ///
  301. /// This parser creates an instance of a single option definition.
  302. class OptionDefParser : public isc::data::SimpleParser {
  303. public:
  304. /// @brief Parses an entry that describes single option definition.
  305. ///
  306. /// @param option_def a configuration entry to be parsed.
  307. /// @return tuple (option definition, option space) of the parsed structure
  308. ///
  309. /// @throw DhcpConfigError if parsing was unsuccessful.
  310. OptionDefinitionTuple
  311. parse(isc::data::ConstElementPtr option_def);
  312. };
  313. /// @brief Parser for a list of option definitions.
  314. ///
  315. /// This parser iterates over all configuration entries that define
  316. /// option definitions and creates instances of these definitions.
  317. /// If the parsing is successful, the collection of created definitions
  318. /// is put into the provided storage.
  319. class OptionDefListParser : public isc::data::SimpleParser {
  320. public:
  321. /// @brief Parses a list of option definitions, create them and store in cfg
  322. ///
  323. /// This method iterates over def_list, which is a JSON list of option definitions,
  324. /// then creates corresponding option definitions and store them in the
  325. /// configuration structure.
  326. ///
  327. /// @param def_list JSON list describing option definitions
  328. /// @param cfg parsed option definitions will be stored here
  329. void parse(CfgOptionDefPtr cfg, isc::data::ConstElementPtr def_list);
  330. };
  331. /// @brief a collection of pools
  332. ///
  333. /// That type is used as intermediate storage, when pools are parsed, but there is
  334. /// no subnet object created yet to store them.
  335. typedef std::vector<PoolPtr> PoolStorage;
  336. typedef boost::shared_ptr<PoolStorage> PoolStoragePtr;
  337. /// @brief parser for a single pool definition
  338. ///
  339. /// This abstract parser handles pool definitions, i.e. a list of entries of one
  340. /// of two syntaxes: min-max and prefix/len. Pool objects are created
  341. /// and stored in chosen PoolStorage container.
  342. ///
  343. /// It is useful for parsing Dhcp<4/6>/subnet<4/6>[X]/pools[X] structure.
  344. class PoolParser : public isc::data::SimpleParser {
  345. public:
  346. /// @brief destructor.
  347. virtual ~PoolParser() {
  348. }
  349. /// @brief parses the actual structure
  350. ///
  351. /// This method parses the actual list of interfaces.
  352. /// No validation is done at this stage, everything is interpreted as
  353. /// interface name.
  354. /// @param pools is the storage in which to store the parsed pool
  355. /// @param pool_structure a single entry on a list of pools
  356. /// @param address_family AF_INET (for DHCPv4) or AF_INET6 (for DHCPv6).
  357. /// @throw isc::dhcp::DhcpConfigError when pool parsing fails
  358. virtual void parse(PoolStoragePtr pools,
  359. isc::data::ConstElementPtr pool_structure,
  360. const uint16_t address_family);
  361. protected:
  362. /// @brief Creates a Pool object given a IPv4 prefix and the prefix length.
  363. ///
  364. /// @param addr is the IP prefix of the pool.
  365. /// @param len is the prefix length.
  366. /// @param ptype is the type of pool to create.
  367. /// @return returns a PoolPtr to the new Pool object.
  368. virtual PoolPtr poolMaker(isc::asiolink::IOAddress &addr, uint32_t len,
  369. int32_t ptype = 0) = 0;
  370. /// @brief Creates a Pool object given starting and ending IP addresses.
  371. ///
  372. /// @param min is the first IP address in the pool.
  373. /// @param max is the last IP address in the pool.
  374. /// @param ptype is the type of pool to create (not used by all derivations)
  375. /// @return returns a PoolPtr to the new Pool object.
  376. virtual PoolPtr poolMaker(isc::asiolink::IOAddress &min,
  377. isc::asiolink::IOAddress &max,
  378. int32_t ptype = 0) = 0;
  379. };
  380. /// @brief Parser for IPv4 pool definitions.
  381. ///
  382. /// This is the IPv4 derivation of the PoolParser class and handles pool
  383. /// definitions, i.e. a list of entries of one of two syntaxes: min-max and
  384. /// prefix/len for IPv4 pools. Pool4 objects are created and stored in chosen
  385. /// PoolStorage container.
  386. ///
  387. /// It is useful for parsing Dhcp4/subnet4[X]/pool parameters.
  388. class Pool4Parser : public PoolParser {
  389. protected:
  390. /// @brief Creates a Pool4 object given a IPv4 prefix and the prefix length.
  391. ///
  392. /// @param addr is the IPv4 prefix of the pool.
  393. /// @param len is the prefix length.
  394. /// @param ignored dummy parameter to provide symmetry between the
  395. /// PoolParser derivations. The V6 derivation requires a third value.
  396. /// @return returns a PoolPtr to the new Pool4 object.
  397. PoolPtr poolMaker (asiolink::IOAddress &addr, uint32_t len,
  398. int32_t ignored);
  399. /// @brief Creates a Pool4 object given starting and ending IPv4 addresses.
  400. ///
  401. /// @param min is the first IPv4 address in the pool.
  402. /// @param max is the last IPv4 address in the pool.
  403. /// @param ignored dummy parameter to provide symmetry between the
  404. /// PoolParser derivations. The V6 derivation requires a third value.
  405. /// @return returns a PoolPtr to the new Pool4 object.
  406. PoolPtr poolMaker (asiolink::IOAddress &min, asiolink::IOAddress &max,
  407. int32_t ignored);
  408. };
  409. /// @brief Parser for a list of pools
  410. ///
  411. /// This parser parses a list pools. Each element on that list gets its own
  412. /// parser, created with poolParserMaker() method. That method must be specified
  413. /// for each protocol family (v4 or v6) separately.
  414. class PoolsListParser : public isc::data::SimpleParser {
  415. public:
  416. /// @brief destructor.
  417. virtual ~PoolsListParser() {
  418. }
  419. /// @brief parses the actual structure
  420. ///
  421. /// This method parses the actual list of pools.
  422. ///
  423. /// @param pools is the storage in which to store the parsed pools.
  424. /// @param pools_list a list of pool structures
  425. /// @throw isc::dhcp::DhcpConfigError when pool parsing fails
  426. virtual void parse(PoolStoragePtr pools,
  427. isc::data::ConstElementPtr pools_list) = 0;
  428. };
  429. /// @brief Specialization of the pool list parser for DHCPv4
  430. class Pools4ListParser : PoolsListParser {
  431. public:
  432. /// @brief parses the actual structure
  433. ///
  434. /// This method parses the actual list of pools.
  435. ///
  436. /// @param pools storage container in which to store the parsed pool.
  437. /// @param pools_list a list of pool structures
  438. /// @throw isc::dhcp::DhcpConfigError when pool parsing fails
  439. void parse(PoolStoragePtr pools, data::ConstElementPtr pools_list);
  440. };
  441. /// @brief parser for additional relay information
  442. ///
  443. /// This concrete parser handles RelayInfo structure definitions.
  444. /// So far that structure holds only relay IP (v4 or v6) address, but it
  445. /// is expected that the number of parameters will increase over time.
  446. ///
  447. /// It is useful for parsing Dhcp<4/6>/subnet<4/6>[x]/relay parameters.
  448. class RelayInfoParser : public isc::data::SimpleParser {
  449. public:
  450. /// @brief constructor
  451. /// @param family specifies protocol family (IPv4 or IPv6)
  452. explicit RelayInfoParser(const isc::dhcp::Option::Universe& family);
  453. /// @brief parses the actual relay parameters
  454. ///
  455. /// The elements currently supported are:
  456. /// -# ip-address
  457. ///
  458. /// @param cfg configuration will be stored here
  459. /// @param relay_info JSON structure holding relay parameters to parse
  460. void parse(const isc::dhcp::Subnet::RelayInfoPtr& cfg,
  461. isc::data::ConstElementPtr relay_info);
  462. private:
  463. /// Protocol family (IPv4 or IPv6)
  464. Option::Universe family_;
  465. };
  466. /// @brief this class parses a single subnet
  467. ///
  468. /// There are dedicated @ref Subnet4ConfigParser and @ref Subnet6ConfigParser
  469. /// classes. They provide specialized parse() methods that return Subnet4Ptr
  470. /// or Subnet6Ptr.
  471. ///
  472. /// This class parses the whole subnet definition. This class attempts to
  473. /// unify the code between v4 and v6 as much as possible. As a result, the flow
  474. /// is somewhat complex and it looks as follows:
  475. ///
  476. /// ------- Base class
  477. /// /
  478. /// | /----- Derived class
  479. /// 1. * SubnetXConfigParser::parse() is called.
  480. /// 2. * SubnetConfigParser::parse() is called.
  481. /// 3. * SubnetConfigParser::createSubnet() is called.
  482. /// 4. * SubnetXConfigParser::initSubnet() is called (Subnet4 or Subnet6 is
  483. /// instantiated here and family specific parameters are set)
  484. /// 5. Control returns to createSubnet() (step 3) and common parameters
  485. /// are set.
  486. class SubnetConfigParser : public isc::data::SimpleParser {
  487. public:
  488. /// @brief constructor
  489. ///
  490. /// @param family address family: @c AF_INET or @c AF_INET6
  491. explicit SubnetConfigParser(uint16_t family);
  492. /// @brief virtual destructor (does nothing)
  493. virtual ~SubnetConfigParser() { }
  494. protected:
  495. /// @brief parses a subnet description and returns Subnet{4,6} structure
  496. ///
  497. /// This method is called from specialized (Subnet4ConfigParser or
  498. /// Subnet6ConfigParser) classes.
  499. ///
  500. /// @param subnet pointer to the content of subnet definition
  501. /// @return a pointer to newly created subnet
  502. ///
  503. /// @throw isc::DhcpConfigError if subnet configuration parsing failed.
  504. SubnetPtr parse(isc::data::ConstElementPtr subnet);
  505. /// @brief Instantiates the subnet based on a given IP prefix and prefix
  506. /// length.
  507. ///
  508. /// @param params configuration parameters for that subnet
  509. /// @param addr is the IP prefix of the subnet.
  510. /// @param len is the prefix length
  511. virtual void initSubnet(isc::data::ConstElementPtr params,
  512. isc::asiolink::IOAddress addr, uint8_t len) = 0;
  513. /// @brief Attempts to convert text representation to HRMode enum.
  514. ///
  515. /// Allowed values are "disabled", "off" (alias for disabled),
  516. /// "out-of-pool" and "all". See Subnet::HRMode for their exact meaning.
  517. ///
  518. /// @param txt Host Reservation mode in the textual form.
  519. ///
  520. /// @throw BadValue if the text cannot be converted.
  521. ///
  522. /// @return one of allowed HRMode values
  523. static Subnet::HRMode hrModeFromText(const std::string& txt);
  524. private:
  525. /// @brief Create a new subnet using a data from child parsers.
  526. ///
  527. /// @param data Element map that describes the subnet
  528. /// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing
  529. /// failed.
  530. void createSubnet(isc::data::ConstElementPtr data);
  531. protected:
  532. /// Storage for pools belonging to this subnet.
  533. PoolStoragePtr pools_;
  534. /// Pointer to the created subnet object.
  535. isc::dhcp::SubnetPtr subnet_;
  536. /// @brief Address family: @c AF_INET or @c AF_INET6
  537. uint16_t address_family_;
  538. /// Pointer to relay information
  539. isc::dhcp::Subnet::RelayInfoPtr relay_info_;
  540. /// Pointer to the options configuration.
  541. CfgOptionPtr options_;
  542. };
  543. /// @anchor Subnet4ConfigParser
  544. /// @brief This class parses a single IPv4 subnet.
  545. ///
  546. /// This is the IPv4 derivation of the SubnetConfigParser class and it parses
  547. /// the whole subnet definition. It creates parsersfor received configuration
  548. /// parameters as needed.
  549. class Subnet4ConfigParser : public SubnetConfigParser {
  550. public:
  551. /// @brief Constructor
  552. ///
  553. /// stores global scope parameters, options, option definitions.
  554. Subnet4ConfigParser();
  555. /// @brief Parses a single IPv4 subnet configuration and adds to the
  556. /// Configuration Manager.
  557. ///
  558. /// @param subnet A new subnet being configured.
  559. /// @return a pointer to created Subnet4 object
  560. Subnet4Ptr parse(data::ConstElementPtr subnet);
  561. protected:
  562. /// @brief Instantiates the IPv4 Subnet based on a given IPv4 address
  563. /// and prefix length.
  564. ///
  565. /// @param params Data structure describing a subnet.
  566. /// @param addr is IPv4 address of the subnet.
  567. /// @param len is the prefix length
  568. void initSubnet(data::ConstElementPtr params,
  569. asiolink::IOAddress addr, uint8_t len);
  570. };
  571. /// @brief this class parses list of DHCP4 subnets
  572. ///
  573. /// This is a wrapper parser that handles the whole list of Subnet4
  574. /// definitions. It iterates over all entries and creates Subnet4ConfigParser
  575. /// for each entry.
  576. class Subnets4ListConfigParser : public isc::data::SimpleParser {
  577. public:
  578. /// @brief parses contents of the list
  579. ///
  580. /// Iterates over all entries on the list, parses its content
  581. /// (by instantiating Subnet6ConfigParser) and adds to specified
  582. /// configuration.
  583. ///
  584. /// @param cfg Pointer to server configuration.
  585. /// @param subnets_list pointer to a list of IPv4 subnets
  586. /// @return number of subnets created
  587. size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list);
  588. /// @brief Parses contents of the subnet4 list.
  589. ///
  590. /// @param [out] subnets Container where parsed subnets will be stored.
  591. /// @param subnets_list pointer to a list of IPv4 subnets
  592. /// @return Number of subnets created.
  593. size_t parse(Subnet4Collection& subnets,
  594. data::ConstElementPtr subnets_list);
  595. };
  596. /// @brief Parser for IPv6 pool definitions.
  597. ///
  598. /// This is the IPv6 derivation of the PoolParser class and handles pool
  599. /// definitions, i.e. a list of entries of one of two syntaxes: min-max and
  600. /// prefix/len for IPv6 pools. Pool6 objects are created and stored in chosen
  601. /// PoolStorage container.
  602. ///
  603. /// It is useful for parsing Dhcp6/subnet6[X]/pool parameters.
  604. class Pool6Parser : public PoolParser {
  605. protected:
  606. /// @brief Creates a Pool6 object given a IPv6 prefix and the prefix length.
  607. ///
  608. /// @param addr is the IPv6 prefix of the pool.
  609. /// @param len is the prefix length.
  610. /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
  611. /// passed in as an int32_t and cast to PoolType to accommodate a
  612. /// polymorphic interface.
  613. /// @return returns a PoolPtr to the new Pool4 object.
  614. PoolPtr poolMaker (asiolink::IOAddress &addr, uint32_t len, int32_t ptype);
  615. /// @brief Creates a Pool6 object given starting and ending IPv6 addresses.
  616. ///
  617. /// @param min is the first IPv6 address in the pool.
  618. /// @param max is the last IPv6 address in the pool.
  619. /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
  620. /// passed in as an int32_t and cast to PoolType to accommodate a
  621. /// polymorphic interface.
  622. /// @return returns a PoolPtr to the new Pool4 object.
  623. PoolPtr poolMaker (asiolink::IOAddress &min, asiolink::IOAddress &max,
  624. int32_t ptype);
  625. };
  626. /// @brief Specialization of the pool list parser for DHCPv6
  627. class Pools6ListParser : PoolsListParser {
  628. public:
  629. /// @brief parses the actual structure
  630. ///
  631. /// This method parses the actual list of pools.
  632. ///
  633. /// @param pools storage container in which to store the parsed pool.
  634. /// @param pools_list a list of pool structures
  635. /// @throw isc::dhcp::DhcpConfigError when pool parsing fails
  636. void parse(PoolStoragePtr pools, data::ConstElementPtr pools_list);
  637. };
  638. /// @brief Parser for IPv6 prefix delegation definitions.
  639. ///
  640. /// This class handles prefix delegation pool definitions for IPv6 subnets
  641. /// Pool6 objects are created and stored in the given PoolStorage container.
  642. ///
  643. /// PdPool definitions currently support three elements: prefix, prefix-len,
  644. /// and delegated-len, as shown in the example JSON text below:
  645. ///
  646. /// @code
  647. ///
  648. /// {
  649. /// "prefix": "2001:db8:1::",
  650. /// "prefix-len": 64,
  651. /// "delegated-len": 128
  652. /// }
  653. /// @endcode
  654. ///
  655. class PdPoolParser : public isc::data::SimpleParser {
  656. public:
  657. /// @brief Constructor.
  658. ///
  659. PdPoolParser();
  660. /// @brief Builds a prefix delegation pool from the given configuration
  661. ///
  662. /// This function parses configuration entries and creates an instance
  663. /// of a dhcp::Pool6 configured for prefix delegation.
  664. ///
  665. /// @param pools storage container in which to store the parsed pool.
  666. /// @param pd_pool_ pointer to an element that holds configuration entries
  667. /// that define a prefix delegation pool.
  668. ///
  669. /// @throw DhcpConfigError if configuration parsing fails.
  670. void parse(PoolStoragePtr pools, data::ConstElementPtr pd_pool_);
  671. private:
  672. /// Pointer to the created pool object.
  673. isc::dhcp::Pool6Ptr pool_;
  674. /// A storage for pool specific option values.
  675. CfgOptionPtr options_;
  676. isc::data::ConstElementPtr user_context_;
  677. };
  678. /// @brief Parser for a list of prefix delegation pools.
  679. ///
  680. /// This parser iterates over a list of prefix delegation pool entries and
  681. /// creates pool instances for each one. If the parsing is successful, the
  682. /// collection of pools is committed to the provided storage.
  683. class PdPoolsListParser : public PoolsListParser {
  684. public:
  685. /// @brief Parse configuration entries.
  686. ///
  687. /// This function parses configuration entries and creates instances
  688. /// of prefix delegation pools .
  689. ///
  690. /// @param storage is the pool storage in which to store the parsed
  691. /// @param pd_pool_list pointer to an element that holds entries
  692. /// that define a prefix delegation pool.
  693. ///
  694. /// @throw DhcpConfigError if configuration parsing fails.
  695. void parse(PoolStoragePtr pools, data::ConstElementPtr pd_pool_list);
  696. };
  697. /// @anchor Subnet6ConfigParser
  698. /// @brief This class parses a single IPv6 subnet.
  699. ///
  700. /// This is the IPv6 derivation of the SubnetConfigParser class and it parses
  701. /// the whole subnet definition. It creates parsersfor received configuration
  702. /// parameters as needed.
  703. class Subnet6ConfigParser : public SubnetConfigParser {
  704. public:
  705. /// @brief Constructor
  706. ///
  707. /// stores global scope parameters, options, option definitions.
  708. Subnet6ConfigParser();
  709. /// @brief Parses a single IPv6 subnet configuration and adds to the
  710. /// Configuration Manager.
  711. ///
  712. /// @param subnet A new subnet being configured.
  713. /// @return a pointer to created Subnet6 object
  714. Subnet6Ptr parse(data::ConstElementPtr subnet);
  715. protected:
  716. /// @brief Issues a DHCP6 server specific warning regarding duplicate subnet
  717. /// options.
  718. ///
  719. /// @param code is the numeric option code of the duplicate option
  720. /// @param addr is the subnet address
  721. /// @todo A means to know the correct logger and perhaps a common
  722. /// message would allow this message to be emitted by the base class.
  723. virtual void duplicate_option_warning(uint32_t code,
  724. asiolink::IOAddress& addr);
  725. /// @brief Instantiates the IPv6 Subnet based on a given IPv6 address
  726. /// and prefix length.
  727. ///
  728. /// @param params Data structure describing a subnet.
  729. /// @param addr is IPv6 prefix of the subnet.
  730. /// @param len is the prefix length
  731. void initSubnet(isc::data::ConstElementPtr params,
  732. isc::asiolink::IOAddress addr, uint8_t len);
  733. };
  734. /// @brief this class parses a list of DHCP6 subnets
  735. ///
  736. /// This is a wrapper parser that handles the whole list of Subnet6
  737. /// definitions. It iterates over all entries and creates Subnet6ConfigParser
  738. /// for each entry.
  739. class Subnets6ListConfigParser : public isc::data::SimpleParser {
  740. public:
  741. /// @brief parses contents of the list
  742. ///
  743. /// Iterates over all entries on the list, parses its content
  744. /// (by instantiating Subnet6ConfigParser) and adds to specified
  745. /// configuration.
  746. ///
  747. /// @param cfg configuration (parsed subnets will be stored here)
  748. /// @param subnets_list pointer to a list of IPv6 subnets
  749. /// @throw DhcpConfigError if CfgMgr rejects the subnet (e.g. subnet-id is a duplicate)
  750. size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list);
  751. /// @brief Parses contents of the subnet6 list.
  752. ///
  753. /// @param [out] subnets Container where parsed subnets will be stored.
  754. /// @param subnets_list pointer to a list of IPv6 subnets
  755. /// @return Number of subnets created.
  756. size_t parse(Subnet6Collection& subnets,
  757. data::ConstElementPtr subnets_list);
  758. };
  759. /// @brief Parser for D2ClientConfig
  760. ///
  761. /// This class parses the configuration element "dhcp-ddns" common to the
  762. /// config files for both dhcp4 and dhcp6. It creates an instance of a
  763. /// D2ClientConfig.
  764. class D2ClientConfigParser : public isc::data::SimpleParser {
  765. public:
  766. /// @brief Parses a given dhcp-ddns element into D2ClientConfig.
  767. ///
  768. /// @param d2_client_cfg is the "dhcp-ddns" configuration to parse
  769. ///
  770. /// The elements currently supported are (see isc::dhcp::D2ClientConfig
  771. /// for details on each):
  772. /// -# enable-updates
  773. /// -# qualifying-suffix
  774. /// -# server-ip
  775. /// -# server-port
  776. /// -# sender-ip
  777. /// -# sender-port
  778. /// -# max-queue-size
  779. /// -# ncr-protocol
  780. /// -# ncr-format
  781. /// -# always-include-fqdn
  782. /// -# override-no-update
  783. /// -# override-client-update
  784. /// -# replace-client-name
  785. /// -# generated-prefix
  786. ///
  787. /// @return returns a pointer to newly created D2ClientConfig.
  788. D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg);
  789. /// @brief Defaults for the D2 client configuration.
  790. static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS;
  791. /// @brief Sets all defaults for D2 client configuration.
  792. ///
  793. /// This method sets defaults value. It must not be called
  794. /// before the short cut disabled updates condition was checked.
  795. ///
  796. /// @param d2_config d2 client configuration (will be const cast
  797. // to ElementPtr)
  798. /// @return number of parameters inserted
  799. static size_t setAllDefaults(isc::data::ConstElementPtr d2_config);
  800. private:
  801. /// @brief Returns a value converted to NameChangeProtocol
  802. ///
  803. /// Instantiation of getAndConvert() to NameChangeProtocol
  804. ///
  805. /// @param scope specified parameter will be extracted from this scope
  806. /// @param name name of the parameter
  807. /// @return a NameChangeProtocol value
  808. dhcp_ddns::NameChangeProtocol
  809. getProtocol(isc::data::ConstElementPtr scope, const std::string& name);
  810. /// @brief Returns a value converted to NameChangeFormat
  811. ///
  812. /// Instantiation of getAndConvert() to NameChangeFormat
  813. ///
  814. /// @param scope specified parameter will be extracted from this scope
  815. /// @param name name of the parameter
  816. /// @return a NameChangeFormat value
  817. dhcp_ddns::NameChangeFormat
  818. getFormat(isc::data::ConstElementPtr scope, const std::string& name);
  819. /// @brief Returns a value converted to ReplaceClientNameMode
  820. ///
  821. /// Instantiation of getAndConvert() to ReplaceClientNameMode
  822. ///
  823. /// @param scope specified parameter will be extracted from this scope
  824. /// @param name name of the parameter
  825. /// @return a NameChangeFormat value
  826. D2ClientConfig::ReplaceClientNameMode
  827. getMode(isc::data::ConstElementPtr scope, const std::string& name);
  828. };
  829. }; // end of isc::dhcp namespace
  830. }; // end of isc namespace
  831. #endif // DHCP_PARSERS_H