libdhcp++.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright (C) 2011-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 LIBDHCP_H
  7. #define LIBDHCP_H
  8. #include <dhcp/option_definition.h>
  9. #include <dhcp/option_space_container.h>
  10. #include <dhcp/pkt6.h>
  11. #include <util/buffer.h>
  12. #include <util/staged_value.h>
  13. #include <iostream>
  14. #include <stdint.h>
  15. #include <string>
  16. namespace isc {
  17. namespace dhcp {
  18. class LibDHCP {
  19. public:
  20. /// Map of factory functions.
  21. typedef std::map<unsigned short, Option::Factory*> FactoryMap;
  22. /// @brief Returns collection of option definitions.
  23. ///
  24. /// This method returns a collection of option definitions for a specified
  25. /// option space.
  26. ///
  27. /// @param space Option space.
  28. ///
  29. /// @return Pointer to a collection of option definitions.
  30. static const OptionDefContainerPtr& getOptionDefs(const std::string& space);
  31. /// @brief Return the first option definition matching a
  32. /// particular option code.
  33. ///
  34. /// @param space option space.
  35. /// @param code option code.
  36. ///
  37. /// @return reference to an option definition being requested
  38. /// or NULL pointer if option definition has not been found.
  39. static OptionDefinitionPtr getOptionDef(const std::string& space,
  40. const uint16_t code);
  41. /// @brief Return the definition of option having a specified name.
  42. ///
  43. /// @param space option space.
  44. /// @param name Option name.
  45. ///
  46. /// @return Pointer to the option definition or NULL pointer if option
  47. /// definition has not been found.
  48. static OptionDefinitionPtr getOptionDef(const std::string& space,
  49. const std::string& name);
  50. /// @brief Returns vendor option definition for a given vendor-id and code
  51. ///
  52. /// @param u universe (V4 or V6)
  53. /// @param vendor_id enterprise-id for a given vendor
  54. /// @param code option code
  55. /// @return reference to an option definition being requested
  56. /// or NULL pointer if option definition has not been found.
  57. static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u,
  58. const uint32_t vendor_id,
  59. const uint16_t code);
  60. /// @brief Returns vendor option definition for a given vendor-id and
  61. /// option name.
  62. ///
  63. /// @param u Universe (V4 or V6)
  64. /// @param vendor_id Enterprise-id for a given vendor
  65. /// @param name Option name.
  66. ///
  67. /// @return A pointer to an option definition or NULL pointer if
  68. /// no option definition found.
  69. static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u,
  70. const uint32_t vendor_id,
  71. const std::string& name);
  72. /// @brief Returns runtime (non-standard) option definition by space and
  73. /// option code.
  74. ///
  75. /// @param space Option space name.
  76. /// @param code Option code.
  77. ///
  78. /// @return Pointer to option definition or NULL if it doesn't exist.
  79. static OptionDefinitionPtr getRuntimeOptionDef(const std::string& space,
  80. const uint16_t code);
  81. /// @brief Returns runtime (non-standard) option definition by space and
  82. /// option name.
  83. ///
  84. /// @param space Option space name.
  85. /// @param name Option name.
  86. ///
  87. /// @return Pointer to option definition or NULL if it doesn't exist.
  88. static OptionDefinitionPtr getRuntimeOptionDef(const std::string& space,
  89. const std::string& name);
  90. /// @brief Returns runtime (non-standard) option definitions for specified
  91. /// option space name.
  92. ///
  93. /// @param space Option space name.
  94. ///
  95. /// @return Pointer to the container holding option definitions or NULL.
  96. static OptionDefContainerPtr
  97. getRuntimeOptionDefs(const std::string& space);
  98. /// @brief Factory function to create instance of option.
  99. ///
  100. /// Factory method creates instance of specified option. The option
  101. /// to be created has to have corresponding factory function
  102. /// registered with \ref LibDHCP::OptionFactoryRegister.
  103. ///
  104. /// @param u universe of the option (V4 or V6)
  105. /// @param type option-type
  106. /// @param buf option-buffer
  107. ///
  108. /// @return instance of option.
  109. ///
  110. /// @throw isc::InvalidOperation if there is no factory function registered
  111. /// for the specified option type.
  112. static isc::dhcp::OptionPtr optionFactory(isc::dhcp::Option::Universe u,
  113. uint16_t type,
  114. const OptionBuffer& buf);
  115. /// @brief Stores DHCPv4 options in a buffer.
  116. ///
  117. /// Stores all options defined in options containers in a on-wire
  118. /// format in output buffer specified by buf.
  119. ///
  120. /// May throw different exceptions if option assembly fails. There
  121. /// may be different reasons (option too large, option malformed,
  122. /// too many options etc.)
  123. ///
  124. /// This is v4 specific version, which stores Relay Agent Information
  125. /// option and END options last.
  126. ///
  127. /// @param buf output buffer (assembled options will be stored here)
  128. /// @param options collection of options to store to
  129. static void packOptions4(isc::util::OutputBuffer& buf,
  130. const isc::dhcp::OptionCollection& options);
  131. /// @brief Stores DHCPv6 options in a buffer.
  132. ///
  133. /// Stores all options defined in options containers in a on-wire
  134. /// format in output buffer specified by buf.
  135. ///
  136. /// May throw different exceptions if option assembly fails. There
  137. /// may be different reasons (option too large, option malformed,
  138. /// too many options etc.)
  139. ///
  140. /// Currently there's no special logic in it. Options are stored in
  141. /// the order of their option codes.
  142. ///
  143. /// @param buf output buffer (assembled options will be stored here)
  144. /// @param options collection of options to store to
  145. static void packOptions6(isc::util::OutputBuffer& buf,
  146. const isc::dhcp::OptionCollection& options);
  147. /// @brief Parses provided buffer as DHCPv6 options and creates
  148. /// Option objects.
  149. ///
  150. /// Parses provided buffer and stores created Option objects in
  151. /// options container. The last two parameters are optional and
  152. /// are used in relay parsing. If they are specified, relay-msg
  153. /// option is not created, but rather those two parameters are
  154. /// specified to point out where the relay-msg option resides and
  155. /// what is its length. This is a performance optimization that
  156. /// avoids unnecessary copying of potentially large relay-msg
  157. /// option. It is not used for anything, except in the next
  158. /// iteration its content will be treated as buffer to be parsed.
  159. ///
  160. /// @param buf Buffer to be parsed.
  161. /// @param option_space A name of the option space which holds definitions
  162. /// to be used to parse options in the packets.
  163. /// @param options Reference to option container. Options will be
  164. /// put here.
  165. /// @param relay_msg_offset reference to a size_t structure. If specified,
  166. /// offset to beginning of relay_msg option will be stored in it.
  167. /// @param relay_msg_len reference to a size_t structure. If specified,
  168. /// length of the relay_msg option will be stored in it.
  169. /// @return offset to the first byte after the last successfully
  170. /// parsed option
  171. ///
  172. /// @note This function throws when an option type is defined more
  173. /// than once, and it calls option building routines which can throw.
  174. /// Partial parsing does not throw: it is the responsibility of the
  175. /// caller to handle this condition.
  176. static size_t unpackOptions6(const OptionBuffer& buf,
  177. const std::string& option_space,
  178. isc::dhcp::OptionCollection& options,
  179. size_t* relay_msg_offset = 0,
  180. size_t* relay_msg_len = 0);
  181. /// @brief Parses provided buffer as DHCPv4 options and creates
  182. /// Option objects.
  183. ///
  184. /// Parses provided buffer and stores created Option objects
  185. /// in options container.
  186. ///
  187. /// @param buf Buffer to be parsed.
  188. /// @param option_space A name of the option space which holds definitions
  189. /// to be used to parse options in the packets.
  190. /// @param options Reference to option container. Options will be
  191. /// put here.
  192. /// @return offset to the first byte after the last successfully
  193. /// parsed option or the offset of the DHO_END option type.
  194. ///
  195. /// The unpackOptions6 note applies too.
  196. static size_t unpackOptions4(const OptionBuffer& buf,
  197. const std::string& option_space,
  198. isc::dhcp::OptionCollection& options);
  199. /// Registers factory method that produces options of specific option types.
  200. ///
  201. /// @throw isc::BadValue if provided the type is already registered, has
  202. /// too large a value or an invalid universe is specified.
  203. ///
  204. /// @param u universe of the option (V4 or V6)
  205. /// @param type option-type
  206. /// @param factory function pointer
  207. static void OptionFactoryRegister(Option::Universe u,
  208. uint16_t type,
  209. Option::Factory * factory);
  210. /// @brief Returns v4 option definitions for a given vendor
  211. ///
  212. /// @param vendor_id enterprise-id of a given vendor
  213. /// @return a container for a given vendor (or NULL if no option
  214. /// definitions are defined)
  215. static const OptionDefContainerPtr&
  216. getVendorOption4Defs(const uint32_t vendor_id);
  217. /// @brief Returns v6 option definitions for a given vendor
  218. ///
  219. /// @param vendor_id enterprise-id of a given vendor
  220. /// @return a container for a given vendor (or NULL if no option
  221. /// definitions are defined)
  222. static const OptionDefContainerPtr&
  223. getVendorOption6Defs(const uint32_t vendor_id);
  224. /// @brief Parses provided buffer as DHCPv6 vendor options and creates
  225. /// Option objects.
  226. ///
  227. /// Parses provided buffer and stores created Option objects
  228. /// in options container.
  229. ///
  230. /// @param vendor_id enterprise-id of the vendor
  231. /// @param buf Buffer to be parsed.
  232. /// @param options Reference to option container. Suboptions will be
  233. /// put here.
  234. /// @return offset to the first byte after the last successfully
  235. /// parsed suboption
  236. ///
  237. /// @note unpackVendorOptions6 throws when it fails to parse a suboption
  238. /// so the return value is currently always the buffer length.
  239. static size_t unpackVendorOptions6(const uint32_t vendor_id,
  240. const OptionBuffer& buf,
  241. isc::dhcp::OptionCollection& options);
  242. /// @brief Parses provided buffer as DHCPv4 vendor options and creates
  243. /// Option objects.
  244. ///
  245. /// Parses provided buffer and stores created Option objects
  246. /// in options container.
  247. ///
  248. /// @param vendor_id enterprise-id of the vendor
  249. /// @param buf Buffer to be parsed.
  250. /// @param options Reference to option container. Suboptions will be
  251. /// put here.
  252. /// @return offset to the first byte after the last successfully
  253. /// parsed suboption
  254. ///
  255. /// The unpackVendorOptions6 note applies
  256. static size_t unpackVendorOptions4(const uint32_t vendor_id,
  257. const OptionBuffer& buf,
  258. isc::dhcp::OptionCollection& options);
  259. /// @brief Copies option definitions created at runtime.
  260. ///
  261. /// Copied option definitions will be used as "runtime" option definitions.
  262. /// A typical use case is to set option definitions specified by the user
  263. /// in the server configuration. These option definitions should be removed
  264. /// or replaced with new option definitions upon reconfiguration.
  265. ///
  266. /// @param defs Const reference to a container holding option definitions
  267. /// grouped by option spaces.
  268. static void setRuntimeOptionDefs(const OptionDefSpaceContainer& defs);
  269. /// @brief Removes runtime option definitions.
  270. static void clearRuntimeOptionDefs();
  271. /// @brief Reverts uncommitted changes to runtime option definitions.
  272. static void revertRuntimeOptionDefs();
  273. /// @brief Commits runtime option definitions.
  274. static void commitRuntimeOptionDefs();
  275. /// @brief Converts option space name to vendor id.
  276. ///
  277. /// If the option space name is specified in the following format:
  278. /// "vendor-X" where X is an uint32_t number, it is assumed to be
  279. /// a vendor space and the uint32_t number is returned by this function.
  280. /// If the option space name is invalid this method will return 0, which
  281. /// is not a valid vendor-id, to signal an error.
  282. ///
  283. /// @todo remove this function once when the conversion is dealt by the
  284. /// appropriate functions returning options by option space names.
  285. ///
  286. /// @param option_space Option space name.
  287. /// @return vendor id.
  288. static uint32_t optionSpaceToVendorId(const std::string& option_space);
  289. private:
  290. /// Initialize standard DHCPv4 option definitions.
  291. ///
  292. /// The method creates option definitions for all DHCPv4 options.
  293. /// Currently this function is not implemented.
  294. ///
  295. /// @throw std::bad alloc if system went out of memory.
  296. /// @throw MalformedOptionDefinition if any of the definitions
  297. /// are incorrect. This is programming error.
  298. static void initStdOptionDefs4();
  299. /// Initialize standard DHCPv6 option definitions.
  300. ///
  301. /// The method creates option definitions for all DHCPv6 options.
  302. ///
  303. /// @throw std::bad_alloc if system went out of memory.
  304. /// @throw MalformedOptionDefinition if any of the definitions
  305. /// is incorrect. This is a programming error.
  306. static void initStdOptionDefs6();
  307. static void initVendorOptsDocsis4();
  308. static void initVendorOptsDocsis6();
  309. /// Initialize private DHCPv6 option definitions.
  310. static void initVendorOptsIsc6();
  311. /// pointers to factories that produce DHCPv6 options
  312. static FactoryMap v4factories_;
  313. /// pointers to factories that produce DHCPv6 options
  314. static FactoryMap v6factories_;
  315. /// Container with DHCPv4 option definitions.
  316. static OptionDefContainerPtr v4option_defs_;
  317. /// Container with DHCPv6 option definitions.
  318. static OptionDefContainerPtr v6option_defs_;
  319. /// Container that holds option definitions for various option spaces.
  320. static OptionDefContainers option_defs_;
  321. /// Container for v4 vendor option definitions
  322. static VendorOptionDefContainers vendor4_defs_;
  323. /// Container for v6 vendor option definitions
  324. static VendorOptionDefContainers vendor6_defs_;
  325. /// Container for additional option definitions created in runtime.
  326. static util::StagedValue<OptionDefSpaceContainer> runtime_option_defs_;
  327. };
  328. }
  329. }
  330. #endif // LIBDHCP_H