option.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright (C) 2011 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 OPTION_H_
  15. #define OPTION_H_
  16. #include <string>
  17. #include <map>
  18. #include <boost/shared_ptr.hpp>
  19. #include <boost/shared_array.hpp>
  20. namespace isc {
  21. namespace dhcp {
  22. class Option {
  23. public:
  24. /// length of the usual DHCPv4 option header (there are exceptions)
  25. const static size_t OPTION4_HDR_LEN = 2;
  26. /// length of any DHCPv6 option header
  27. const static size_t OPTION6_HDR_LEN = 4;
  28. /// defines option universe DHCPv4 or DHCPv6
  29. enum Universe { V4, V6 };
  30. /// a collection of DHCPv4 options
  31. typedef std::map<unsigned int, boost::shared_ptr<Option> >
  32. Option4Collection;
  33. /// a collection of DHCPv6 options
  34. typedef std::multimap<unsigned int, boost::shared_ptr<Option> >
  35. Option6Collection;
  36. /// @brief a factory function prototype
  37. ///
  38. /// @param u option universe (DHCPv4 or DHCPv6)
  39. /// @param type option type
  40. /// @param buf pointer to a buffer
  41. /// @param offset offset to first data byte in that buffer
  42. /// @param len data length of this option
  43. ///
  44. /// @return a pointer to a created option object
  45. typedef boost::shared_ptr<Option> Factory(Option::Universe u,
  46. unsigned short type,
  47. boost::shared_array<uint8_t>& buf,
  48. unsigned int offset,
  49. unsigned int len);
  50. /// @brief ctor, used for options constructed, usually during transmission
  51. ///
  52. /// @param u option universe (DHCPv4 or DHCPv6)
  53. /// @param type option type
  54. Option(Universe u, unsigned short type);
  55. /// @brief ctor, used for received options
  56. ///
  57. /// boost::shared_array allows sharing a buffer, but it requires that
  58. /// different instances share pointer to the whole array, not point
  59. /// to different elements in shared array. Therefore we need to share
  60. /// pointer to the whole array and remember offset where data for
  61. /// this option begins
  62. ///
  63. /// @param u specifies universe (V4 or V6)
  64. /// @param type option type
  65. /// @param buf pointer to a buffer
  66. /// @param offset offset in a buffer pointing to first byte of data
  67. /// @param len length of the option data
  68. Option(Universe u, unsigned short type,
  69. const boost::shared_array<uint8_t>& buf, unsigned int offset,
  70. unsigned int len);
  71. /// @brief writes option in wire-format to buf
  72. ///
  73. /// Writes option in wire-format to buffer, returns pointer to first unused
  74. /// byte after stored option (that is useful for writing options one after
  75. /// another)
  76. ///
  77. /// @param buf pointer to a buffer
  78. /// @param buf_len length of the buffer
  79. /// @param offset offset to place, where option shout be stored
  80. ///
  81. /// @return offset to first unused byte after stored option
  82. ///
  83. virtual unsigned int
  84. pack(boost::shared_array<uint8_t>& buf,
  85. unsigned int buf_len,
  86. unsigned int offset);
  87. /// @brief Parses buffer.
  88. ///
  89. /// Parses received buffer, returns offset to the first unused byte after
  90. /// parsed option.
  91. ///
  92. /// @param buf pointer to buffer
  93. /// @param buf_len length of buf
  94. /// @param offset offset, where start parsing option
  95. /// @param parse_len how many bytes should be parsed
  96. ///
  97. /// @return offset after last parsed octet
  98. virtual unsigned int
  99. unpack(const boost::shared_array<uint8_t>& buf,
  100. unsigned int buf_len,
  101. unsigned int offset,
  102. unsigned int parse_len);
  103. /// Returns string representation of the option.
  104. ///
  105. /// @param indent number of spaces before printing text
  106. ///
  107. /// @return string with text representation.
  108. virtual std::string
  109. toText(int indent = 0);
  110. /// Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
  111. ///
  112. /// @return option type
  113. unsigned short
  114. getType();
  115. /// Returns length of the complete option (data length + DHCPv4/DHCPv6
  116. /// option header)
  117. ///
  118. /// @return length of the option
  119. virtual unsigned short
  120. len();
  121. /// @brief Returns length of header (2 for v4, 4 for v6)
  122. ///
  123. /// @return length of option header
  124. virtual unsigned short
  125. getHeaderLen();
  126. /// returns if option is valid (e.g. option may be truncated)
  127. ///
  128. /// @return true, if option is valid
  129. virtual bool
  130. valid();
  131. /// Returns pointer to actual data.
  132. ///
  133. /// @return pointer to actual data (or NULL if there is no data)
  134. virtual uint8_t*
  135. getData();
  136. /// Adds a sub-option.
  137. ///
  138. /// Some DHCPv6 options can have suboptions. This method allows adding
  139. /// options within options.
  140. ///
  141. /// Note: option is passed by value. That is very convenient as it allows
  142. /// downcasting from any derived classes, e.g. shared_ptr<Option6_IA> type
  143. /// can be passed directly, without any casts. That would not be possible
  144. /// with passing by reference. addOption() is expected to be used in
  145. /// many places. Requiring casting is not feasible.
  146. ///
  147. /// @param opt shared pointer to a suboption that is going to be added.
  148. void
  149. addOption(boost::shared_ptr<Option> opt);
  150. /// Returns shared_ptr to suboption of specific type
  151. ///
  152. /// @param type type of requested suboption
  153. ///
  154. /// @return shared_ptr to requested suoption
  155. boost::shared_ptr<isc::dhcp::Option>
  156. getOption(unsigned short type);
  157. /// Attempts to delete first suboption of requested type
  158. ///
  159. /// @param type Type of option to be deleted.
  160. ///
  161. /// @return true if option was deleted, false if no such option existed
  162. bool
  163. delOption(unsigned short type);
  164. /// just to force that every option has virtual dtor
  165. virtual
  166. ~Option();
  167. protected:
  168. /// Builds raw (over-wire) buffer of this option, including all
  169. /// defined suboptions. Version for building DHCPv4 options.
  170. ///
  171. /// @param buf output buffer (built options will be stored here)
  172. /// @param buf_len buffer length (used for buffer overflow checks)
  173. /// @param offset offset from start of the buf buffer
  174. ///
  175. /// @return offset to the next byte after last used byte
  176. virtual unsigned int
  177. pack4(boost::shared_array<uint8_t>& buf,
  178. unsigned int buf_len,
  179. unsigned int offset);
  180. /// Builds raw (over-wire) buffer of this option, including all
  181. /// defined suboptions. Version for building DHCPv4 options.
  182. ///
  183. /// @param buf output buffer (built options will be stored here)
  184. /// @param buf_len buffer length (used for buffer overflow checks)
  185. /// @param offset offset from start of the buf buffer
  186. ///
  187. /// @return offset to the next byte after last used byte
  188. virtual unsigned int
  189. pack6(boost::shared_array<uint8_t>& buf,
  190. unsigned int buf_len,
  191. unsigned int offset);
  192. /// Parses provided buffer and creates DHCPv4 options.
  193. ///
  194. /// @param buf buffer that contains raw buffer to parse (on-wire format)
  195. /// @param buf_len buffer length (used for buffer overflow checks)
  196. /// @param offset offset from start of the buf buffer
  197. ///
  198. /// @return offset to the next byte after last parsed byte
  199. virtual unsigned int
  200. unpack4(const boost::shared_array<uint8_t>& buf,
  201. unsigned int buf_len,
  202. unsigned int offset,
  203. unsigned int parse_len);
  204. /// Parses provided buffer and creates DHCPv6 options.
  205. ///
  206. /// @param buf buffer that contains raw buffer to parse (on-wire format)
  207. /// @param buf_len buffer length (used for buffer overflow checks)
  208. /// @param offset offset from start of the buf buffer
  209. ///
  210. /// @return offset to the next byte after last parsed byte
  211. virtual unsigned int
  212. unpack6(const boost::shared_array<uint8_t>& buf,
  213. unsigned int buf_len,
  214. unsigned int offset,
  215. unsigned int parse_len);
  216. /// option universe (V4 or V6)
  217. Universe universe_;
  218. /// option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
  219. unsigned short type_;
  220. /// shared pointer to a buffer (usually a part of packet)
  221. boost::shared_array<uint8_t> data_;
  222. /// length of data only. Use len() if you want to
  223. /// know proper length with option header overhead
  224. unsigned int data_len_;
  225. /// data is a shared_pointer that points out to the
  226. /// whole packet. offset_ specifies where data for
  227. /// this option begins.
  228. unsigned int offset_;
  229. /// collection for storing suboptions
  230. Option6Collection options_;
  231. /// TODO: probably 2 different containers have to be used for v4 (unique
  232. /// options) and v6 (options with the same type can repeat)
  233. };
  234. } // namespace isc::dhcp
  235. } // namespace isc
  236. #endif