libdhcp++.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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 Checks if an option unpacking has to be deferred.
  99. ///
  100. /// DHCPv4 option 43 and 224-254 unpacking is done after classification.
  101. ///
  102. /// @space Option space name.
  103. /// @param code Option code.
  104. ///
  105. /// @return True if option processing should be deferred.
  106. static bool deferOption(const std::string& space, const uint16_t code);
  107. /// @brief Last resort definition for DHCPv4 option 43
  108. static OptionDefinitionPtr last_resort_option43_def;
  109. /// @brief Factory function to create instance of option.
  110. ///
  111. /// Factory method creates instance of specified option. The option
  112. /// to be created has to have corresponding factory function
  113. /// registered with \ref LibDHCP::OptionFactoryRegister.
  114. ///
  115. /// @param u universe of the option (V4 or V6)
  116. /// @param type option-type
  117. /// @param buf option-buffer
  118. ///
  119. /// @return instance of option.
  120. ///
  121. /// @throw isc::InvalidOperation if there is no factory function registered
  122. /// for the specified option type.
  123. static isc::dhcp::OptionPtr optionFactory(isc::dhcp::Option::Universe u,
  124. uint16_t type,
  125. const OptionBuffer& buf);
  126. /// @brief Stores DHCPv4 options in a buffer.
  127. ///
  128. /// Stores all options defined in options containers in a on-wire
  129. /// format in output buffer specified by buf.
  130. ///
  131. /// May throw different exceptions if option assembly fails. There
  132. /// may be different reasons (option too large, option malformed,
  133. /// too many options etc.)
  134. ///
  135. /// This is v4 specific version, which stores Relay Agent Information
  136. /// option and END options last.
  137. ///
  138. /// @param buf output buffer (assembled options will be stored here)
  139. /// @param options collection of options to store to
  140. static void packOptions4(isc::util::OutputBuffer& buf,
  141. const isc::dhcp::OptionCollection& options);
  142. /// @brief Stores DHCPv6 options in a buffer.
  143. ///
  144. /// Stores all options defined in options containers in a on-wire
  145. /// format in output buffer specified by buf.
  146. ///
  147. /// May throw different exceptions if option assembly fails. There
  148. /// may be different reasons (option too large, option malformed,
  149. /// too many options etc.)
  150. ///
  151. /// Currently there's no special logic in it. Options are stored in
  152. /// the order of their option codes.
  153. ///
  154. /// @param buf output buffer (assembled options will be stored here)
  155. /// @param options collection of options to store to
  156. static void packOptions6(isc::util::OutputBuffer& buf,
  157. const isc::dhcp::OptionCollection& options);
  158. /// @brief Parses provided buffer as DHCPv6 options and creates
  159. /// Option objects.
  160. ///
  161. /// Parses provided buffer and stores created Option objects in
  162. /// options container. The last two parameters are optional and
  163. /// are used in relay parsing. If they are specified, relay-msg
  164. /// option is not created, but rather those two parameters are
  165. /// specified to point out where the relay-msg option resides and
  166. /// what is its length. This is a performance optimization that
  167. /// avoids unnecessary copying of potentially large relay-msg
  168. /// option. It is not used for anything, except in the next
  169. /// iteration its content will be treated as buffer to be parsed.
  170. ///
  171. /// @param buf Buffer to be parsed.
  172. /// @param option_space A name of the option space which holds definitions
  173. /// to be used to parse options in the packets.
  174. /// @param options Reference to option container. Options will be
  175. /// put here.
  176. /// @param relay_msg_offset reference to a size_t structure. If specified,
  177. /// offset to beginning of relay_msg option will be stored in it.
  178. /// @param relay_msg_len reference to a size_t structure. If specified,
  179. /// length of the relay_msg option will be stored in it.
  180. /// @return offset to the first byte after the last successfully
  181. /// parsed option
  182. ///
  183. /// @note This function throws when an option type is defined more
  184. /// than once, and it calls option building routines which can throw.
  185. /// Partial parsing does not throw: it is the responsibility of the
  186. /// caller to handle this condition.
  187. static size_t unpackOptions6(const OptionBuffer& buf,
  188. const std::string& option_space,
  189. isc::dhcp::OptionCollection& options,
  190. size_t* relay_msg_offset = 0,
  191. size_t* relay_msg_len = 0);
  192. /// @brief Parses provided buffer as DHCPv4 options and creates
  193. /// Option objects.
  194. ///
  195. /// Parses provided buffer and stores created Option objects
  196. /// in options container.
  197. ///
  198. /// @param buf Buffer to be parsed.
  199. /// @param option_space A name of the option space which holds definitions
  200. /// to be used to parse options in the packets.
  201. /// @param options Reference to option container. Options will be
  202. /// put here.
  203. /// @return offset to the first byte after the last successfully
  204. /// parsed option or the offset of the DHO_END option type.
  205. ///
  206. /// The unpackOptions6 note applies too.
  207. static size_t unpackOptions4(const OptionBuffer& buf,
  208. const std::string& option_space,
  209. isc::dhcp::OptionCollection& options);
  210. /// Registers factory method that produces options of specific option types.
  211. ///
  212. /// @throw isc::BadValue if provided the type is already registered, has
  213. /// too large a value or an invalid universe is specified.
  214. ///
  215. /// @param u universe of the option (V4 or V6)
  216. /// @param type option-type
  217. /// @param factory function pointer
  218. static void OptionFactoryRegister(Option::Universe u,
  219. uint16_t type,
  220. Option::Factory * factory);
  221. /// @brief Returns v4 option definitions for a given vendor
  222. ///
  223. /// @param vendor_id enterprise-id of a given vendor
  224. /// @return a container for a given vendor (or NULL if no option
  225. /// definitions are defined)
  226. static const OptionDefContainerPtr&
  227. getVendorOption4Defs(const uint32_t vendor_id);
  228. /// @brief Returns v6 option definitions for a given vendor
  229. ///
  230. /// @param vendor_id enterprise-id of a given vendor
  231. /// @return a container for a given vendor (or NULL if no option
  232. /// definitions are defined)
  233. static const OptionDefContainerPtr&
  234. getVendorOption6Defs(const uint32_t vendor_id);
  235. /// @brief Parses provided buffer as DHCPv6 vendor options and creates
  236. /// Option objects.
  237. ///
  238. /// Parses provided buffer and stores created Option objects
  239. /// in options container.
  240. ///
  241. /// @param vendor_id enterprise-id of the vendor
  242. /// @param buf Buffer to be parsed.
  243. /// @param options Reference to option container. Suboptions will be
  244. /// put here.
  245. /// @return offset to the first byte after the last successfully
  246. /// parsed suboption
  247. ///
  248. /// @note unpackVendorOptions6 throws when it fails to parse a suboption
  249. /// so the return value is currently always the buffer length.
  250. static size_t unpackVendorOptions6(const uint32_t vendor_id,
  251. const OptionBuffer& buf,
  252. isc::dhcp::OptionCollection& options);
  253. /// @brief Parses provided buffer as DHCPv4 vendor options and creates
  254. /// Option objects.
  255. ///
  256. /// Parses provided buffer and stores created Option objects
  257. /// in options container.
  258. ///
  259. /// @param vendor_id enterprise-id of the vendor
  260. /// @param buf Buffer to be parsed.
  261. /// @param options Reference to option container. Suboptions will be
  262. /// put here.
  263. /// @return offset to the first byte after the last successfully
  264. /// parsed suboption
  265. ///
  266. /// The unpackVendorOptions6 note applies
  267. static size_t unpackVendorOptions4(const uint32_t vendor_id,
  268. const OptionBuffer& buf,
  269. isc::dhcp::OptionCollection& options);
  270. /// @brief Copies option definitions created at runtime.
  271. ///
  272. /// Copied option definitions will be used as "runtime" option definitions.
  273. /// A typical use case is to set option definitions specified by the user
  274. /// in the server configuration. These option definitions should be removed
  275. /// or replaced with new option definitions upon reconfiguration.
  276. ///
  277. /// @param defs Const reference to a container holding option definitions
  278. /// grouped by option spaces.
  279. static void setRuntimeOptionDefs(const OptionDefSpaceContainer& defs);
  280. /// @brief Removes runtime option definitions.
  281. static void clearRuntimeOptionDefs();
  282. /// @brief Reverts uncommitted changes to runtime option definitions.
  283. static void revertRuntimeOptionDefs();
  284. /// @brief Commits runtime option definitions.
  285. static void commitRuntimeOptionDefs();
  286. /// @brief Converts option space name to vendor id.
  287. ///
  288. /// If the option space name is specified in the following format:
  289. /// "vendor-X" where X is an uint32_t number, it is assumed to be
  290. /// a vendor space and the uint32_t number is returned by this function.
  291. /// If the option space name is invalid this method will return 0, which
  292. /// is not a valid vendor-id, to signal an error.
  293. ///
  294. /// @todo remove this function once when the conversion is dealt by the
  295. /// appropriate functions returning options by option space names.
  296. ///
  297. /// @param option_space Option space name.
  298. /// @return vendor id.
  299. static uint32_t optionSpaceToVendorId(const std::string& option_space);
  300. private:
  301. /// Initialize standard DHCPv4 option definitions.
  302. ///
  303. /// The method creates option definitions for all DHCPv4 options.
  304. /// Currently this function is not implemented.
  305. ///
  306. /// @throw std::bad alloc if system went out of memory.
  307. /// @throw MalformedOptionDefinition if any of the definitions
  308. /// are incorrect. This is programming error.
  309. static void initStdOptionDefs4();
  310. /// Initialize standard DHCPv6 option definitions.
  311. ///
  312. /// The method creates option definitions for all DHCPv6 options.
  313. ///
  314. /// @throw std::bad_alloc if system went out of memory.
  315. /// @throw MalformedOptionDefinition if any of the definitions
  316. /// is incorrect. This is a programming error.
  317. static void initStdOptionDefs6();
  318. static void initVendorOptsDocsis4();
  319. static void initVendorOptsDocsis6();
  320. /// Initialize private DHCPv6 option definitions.
  321. static void initVendorOptsIsc6();
  322. /// pointers to factories that produce DHCPv6 options
  323. static FactoryMap v4factories_;
  324. /// pointers to factories that produce DHCPv6 options
  325. static FactoryMap v6factories_;
  326. /// Container with DHCPv4 option definitions.
  327. static OptionDefContainerPtr v4option_defs_;
  328. /// Container with DHCPv6 option definitions.
  329. static OptionDefContainerPtr v6option_defs_;
  330. /// Container that holds option definitions for various option spaces.
  331. static OptionDefContainers option_defs_;
  332. /// Container for v4 vendor option definitions
  333. static VendorOptionDefContainers vendor4_defs_;
  334. /// Container for v6 vendor option definitions
  335. static VendorOptionDefContainers vendor6_defs_;
  336. /// Container for additional option definitions created in runtime.
  337. static util::StagedValue<OptionDefSpaceContainer> runtime_option_defs_;
  338. };
  339. }
  340. }
  341. #endif // LIBDHCP_H