libdhcp++.h 15 KB

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