libdhcp++.h 15 KB

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