option6_iaprefix_unittest.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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. #include <config.h>
  15. #include <dhcp/dhcp6.h>
  16. #include <dhcp/option.h>
  17. #include <dhcp/option6_iaprefix.h>
  18. #include <util/buffer.h>
  19. #include <boost/scoped_ptr.hpp>
  20. #include <gtest/gtest.h>
  21. #include <iostream>
  22. #include <sstream>
  23. #include <arpa/inet.h>
  24. using namespace std;
  25. using namespace isc;
  26. using namespace isc::dhcp;
  27. using namespace isc::util;
  28. using namespace isc::asiolink;
  29. namespace {
  30. class Option6IAPrefixTest : public ::testing::Test {
  31. public:
  32. Option6IAPrefixTest() : buf_(255), out_buf_(255) {
  33. for (unsigned i = 0; i < 255; i++) {
  34. buf_[i] = 255 - i;
  35. }
  36. }
  37. /// @brief creates on-wire representation of IAPREFIX option
  38. ///
  39. /// buf_ field is set up to have IAPREFIX with preferred=1000,
  40. /// valid=3000000000 and prefix being 2001:db8:1:0:afaf:0:dead:beef/77
  41. void setExampleBuffer() {
  42. for (int i = 0; i < 255; i++) {
  43. buf_[i] = 0;
  44. }
  45. buf_[ 0] = 0x00;
  46. buf_[ 1] = 0x00;
  47. buf_[ 2] = 0x03;
  48. buf_[ 3] = 0xe8; // preferred lifetime = 1000
  49. buf_[ 4] = 0xb2;
  50. buf_[ 5] = 0xd0;
  51. buf_[ 6] = 0x5e;
  52. buf_[ 7] = 0x00; // valid lifetime = 3,000,000,000
  53. buf_[ 8] = 77; // Prefix length = 77
  54. buf_[ 9] = 0x20;
  55. buf_[10] = 0x01;
  56. buf_[11] = 0x0d;
  57. buf_[12] = 0xb8;
  58. buf_[13] = 0x00;
  59. buf_[14] = 0x01;
  60. buf_[17] = 0xaf;
  61. buf_[18] = 0xaf;
  62. buf_[21] = 0xde;
  63. buf_[22] = 0xad;
  64. buf_[23] = 0xbe;
  65. buf_[24] = 0xef; // 2001:db8:1:0:afaf:0:dead:beef
  66. }
  67. /// @brief Checks whether specified IAPREFIX option meets expected values
  68. ///
  69. /// To be used with option generated by setExampleBuffer
  70. ///
  71. /// @param opt IAPREFIX option being tested
  72. /// @param expected_type expected option type
  73. /// @param expected_length Expected length of the prefix.
  74. /// @param expected_address Expected prefix value.
  75. void checkOption(Option6IAPrefix& opt, const uint16_t expected_type,
  76. const uint8_t expected_length,
  77. const IOAddress& expected_address) {
  78. // Check if all fields have expected values
  79. EXPECT_EQ(Option::V6, opt.getUniverse());
  80. EXPECT_EQ(expected_type, opt.getType());
  81. EXPECT_EQ(expected_address, opt.getAddress());
  82. EXPECT_EQ(1000, opt.getPreferred());
  83. EXPECT_EQ(3000000000U, opt.getValid());
  84. // uint8_t is often represented as a character type (char). Convert it
  85. // to integer so as it is logged as a numeric value instead.
  86. EXPECT_EQ(static_cast<int>(expected_length),
  87. static_cast<int>(opt.getLength()));
  88. // 4 bytes header + 25 bytes content
  89. EXPECT_EQ(Option::OPTION6_HDR_LEN + Option6IAPrefix::OPTION6_IAPREFIX_LEN,
  90. opt.len());
  91. }
  92. /// @brief Checks whether content of output buffer is correct
  93. ///
  94. /// Output buffer is expected to be filled with an option matchin
  95. /// buf_ content as defined in setExampleBuffer().
  96. ///
  97. /// @param expected_type expected option type
  98. void checkOutputBuffer(uint16_t expected_type) {
  99. // Check if pack worked properly:
  100. const uint8_t* out = static_cast<const uint8_t*>(out_buf_.getData());
  101. // - if option type is correct
  102. EXPECT_EQ(expected_type, out[0]*256 + out[1]);
  103. // - if option length is correct
  104. EXPECT_EQ(25, out[2]*256 + out[3]);
  105. // - if option content is correct
  106. EXPECT_EQ(0, memcmp(out + 4, &buf_[0], 25));
  107. }
  108. OptionBuffer buf_;
  109. OutputBuffer out_buf_;
  110. };
  111. // Tests if a received option is parsed correctly. For the prefix length between
  112. // 0 and 128 the non-significant bits should be set to 0.
  113. TEST_F(Option6IAPrefixTest, parseShort) {
  114. setExampleBuffer();
  115. // Create an option (unpack content)
  116. boost::scoped_ptr<Option6IAPrefix> opt;
  117. ASSERT_NO_THROW(opt.reset(new Option6IAPrefix(D6O_IAPREFIX, buf_.begin(),
  118. buf_.begin() + 25)));
  119. ASSERT_TRUE(opt);
  120. // Pack this option
  121. opt->pack(out_buf_);
  122. EXPECT_EQ(29, out_buf_.getLength());
  123. // The non-significant bits (above 77) of the received prefix should be
  124. // set to zero.
  125. checkOption(*opt, D6O_IAPREFIX, 77, IOAddress("2001:db8:1:0:afa8::"));
  126. // Set non-significant bits in the reference buffer to 0, so as the buffer
  127. // can be directly compared with the option buffer.
  128. buf_[18] = 0xa8;
  129. buf_.insert(buf_.begin() + 19, 5, 0);
  130. checkOutputBuffer(D6O_IAPREFIX);
  131. // Check that option can be disposed safely
  132. EXPECT_NO_THROW(opt.reset());
  133. }
  134. // Tests if a received option holding prefix of 128 bits is parsed correctly.
  135. TEST_F(Option6IAPrefixTest, parseLong) {
  136. setExampleBuffer();
  137. // Set prefix length to the maximal value.
  138. buf_[8] = 128;
  139. // Create an option (unpack content)
  140. boost::scoped_ptr<Option6IAPrefix> opt;
  141. ASSERT_NO_THROW(opt.reset(new Option6IAPrefix(D6O_IAPREFIX, buf_.begin(),
  142. buf_.begin() + 25)));
  143. ASSERT_TRUE(opt);
  144. // Pack this option
  145. opt->pack(out_buf_);
  146. EXPECT_EQ(29, out_buf_.getLength());
  147. checkOption(*opt, D6O_IAPREFIX, 128,
  148. IOAddress("2001:db8:1:0:afaf:0:dead:beef"));
  149. checkOutputBuffer(D6O_IAPREFIX);
  150. // Check that option can be disposed safely
  151. EXPECT_NO_THROW(opt.reset());
  152. }
  153. // Check that the prefix having length of zero is represented as a "::".
  154. TEST_F(Option6IAPrefixTest, parseZero) {
  155. setExampleBuffer();
  156. // Set prefix length to 0.
  157. buf_[8] = 0;
  158. // Create an option (unpack content)
  159. boost::scoped_ptr<Option6IAPrefix> opt;
  160. ASSERT_NO_THROW(opt.reset(new Option6IAPrefix(D6O_IAPREFIX, buf_.begin(),
  161. buf_.begin() + 25)));
  162. ASSERT_TRUE(opt);
  163. // Pack this option
  164. opt->pack(out_buf_);
  165. EXPECT_EQ(29, out_buf_.getLength());
  166. checkOption(*opt, D6O_IAPREFIX, 0, IOAddress("::"));
  167. // Fill the address in the reference buffer with zeros.
  168. buf_.insert(buf_.begin() + 9, 16, 0);
  169. checkOutputBuffer(D6O_IAPREFIX);
  170. // Check that option can be disposed safely
  171. EXPECT_NO_THROW(opt.reset());
  172. }
  173. // Checks whether a new option can be built correctly
  174. TEST_F(Option6IAPrefixTest, build) {
  175. boost::scoped_ptr<Option6IAPrefix> opt;
  176. setExampleBuffer();
  177. ASSERT_NO_THROW(opt.reset(new Option6IAPrefix(12345,
  178. IOAddress("2001:db8:1:0:afaf:0:dead:beef"), 77,
  179. 1000, 3000000000u)));
  180. ASSERT_TRUE(opt);
  181. checkOption(*opt, 12345, 77, IOAddress("2001:db8:1:0:afaf:0:dead:beef"));
  182. // Check if we can build it properly
  183. EXPECT_NO_THROW(opt->pack(out_buf_));
  184. EXPECT_EQ(29, out_buf_.getLength());
  185. checkOutputBuffer(12345);
  186. // Check that option can be disposed safely
  187. EXPECT_NO_THROW(opt.reset());
  188. }
  189. // Checks negative cases
  190. TEST_F(Option6IAPrefixTest, negative) {
  191. // Truncated option (at least 25 bytes is needed)
  192. EXPECT_THROW(Option6IAPrefix(D6O_IAPREFIX, buf_.begin(), buf_.begin() + 24),
  193. OutOfRange);
  194. // Empty option
  195. EXPECT_THROW(Option6IAPrefix(D6O_IAPREFIX, buf_.begin(), buf_.begin()),
  196. OutOfRange);
  197. // This is for IPv6 prefixes only
  198. EXPECT_THROW(Option6IAPrefix(12345, IOAddress("192.0.2.1"), 77, 1000, 2000),
  199. BadValue);
  200. // Prefix length can't be larger than 128
  201. EXPECT_THROW(Option6IAPrefix(12345, IOAddress("192.0.2.1"),
  202. 255, 1000, 2000),
  203. BadValue);
  204. }
  205. }