option6_int.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (C) 2012 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_INT6_H_
  15. #define OPTION_INT6_H_
  16. #include <stdint.h>
  17. #include <limits>
  18. #include <util/io_utilities.h>
  19. #include "dhcp/libdhcp++.h"
  20. #include "dhcp/option.h"
  21. #include "dhcp/option_data_types.h"
  22. namespace isc {
  23. namespace dhcp {
  24. /// This template class represents DHCPv6 option with single value.
  25. /// This value is of integer type and can be any of the following:
  26. /// - uint8_t,
  27. /// - uint16_t,
  28. /// - uint32_t,
  29. /// - int8_t,
  30. /// - int16_t,
  31. /// - int32_t.
  32. ///
  33. /// @param T data field type (see above).
  34. template<typename T>
  35. class Option6Int: public Option {
  36. public:
  37. /// @brief Constructor.
  38. ///
  39. /// @param type option type.
  40. /// @param value option value.
  41. Option6Int(uint16_t type, T value)
  42. : Option(Option::V6, type), value_(value) {
  43. if (!OptionDataTypes<T>::valid) {
  44. isc_throw(dhcp::InvalidDataType, "non-numeric type");
  45. }
  46. }
  47. /// @brief Constructor.
  48. ///
  49. /// This constructor creates option from a buffer. This construtor
  50. /// may throw exception if \ref unpack function throws during buffer
  51. /// parsing.
  52. ///
  53. /// @param type option type.
  54. /// @param begin iterator to first byte of option data.
  55. /// @param end iterator to end of option data (first byte after option end).
  56. ///
  57. /// @todo mention here what it throws.
  58. Option6Int(uint16_t type, OptionBufferConstIter begin,
  59. OptionBufferConstIter end)
  60. : Option(Option::V6, type) {
  61. if (!OptionDataTypes<T>::valid) {
  62. isc_throw(dhcp::InvalidDataType, "non-numeric type");
  63. }
  64. unpack(begin, end);
  65. }
  66. /// Writes option in wire-format to buf, returns pointer to first unused
  67. /// byte after stored option.
  68. ///
  69. /// @param [out] buf buffer (option will be stored here)
  70. ///
  71. /// @throw isc::BadValue if invalid option type has been provided.
  72. void pack(isc::util::OutputBuffer& buf) {
  73. buf.writeUint16(type_);
  74. buf.writeUint16(len() - OPTION6_HDR_LEN);
  75. switch (OptionDataTypes<T>::len) {
  76. case 1:
  77. buf.writeUint8(value_);
  78. break;
  79. case 2:
  80. buf.writeUint16(value_);
  81. break;
  82. case 4:
  83. buf.writeUint32(value_);
  84. break;
  85. default:
  86. isc_throw(dhcp::InvalidDataType, "non-numeric type");
  87. }
  88. }
  89. /// @brief Parses received buffer
  90. ///
  91. /// Parses received buffer and returns offset to the first unused byte after
  92. /// parsed option.
  93. ///
  94. /// @param begin iterator to first byte of option data
  95. /// @param end iterator to end of option data (first byte after option end)
  96. virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
  97. if (distance(begin, end) < sizeof(T)) {
  98. isc_throw(OutOfRange, "Option " << type_ << " truncated");
  99. }
  100. switch (OptionDataTypes<T>::len) {
  101. case 1:
  102. value_ = *begin;
  103. break;
  104. case 2:
  105. value_ = isc::util::readUint16( &(*begin) );
  106. break;
  107. case 4:
  108. value_ = isc::util::readUint32( &(*begin) );
  109. break;
  110. default:
  111. isc_throw(dhcp::InvalidDataType, "non-numeric type");
  112. }
  113. LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
  114. }
  115. void setValue(T value) { value_ = value; }
  116. T getValue() const { return value_; }
  117. /// @brief returns complete length of option
  118. ///
  119. /// Returns length of this option, including option header and suboptions
  120. ///
  121. /// @return length of this option
  122. virtual uint16_t len() {
  123. uint16_t length = OPTION6_HDR_LEN + sizeof(T);
  124. // length of all suboptions
  125. for (Option::OptionCollection::iterator it = options_.begin();
  126. it != options_.end();
  127. ++it) {
  128. length += (*it).second->len();
  129. }
  130. return (length);
  131. }
  132. private:
  133. T value_;
  134. };
  135. } // isc::dhcp namespace
  136. } // isc namespace
  137. #endif /* OPTION_IA_H_ */