option6_ia_unittest.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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. #include <config.h>
  15. #include <iostream>
  16. #include <sstream>
  17. #include <arpa/inet.h>
  18. #include <gtest/gtest.h>
  19. #include "dhcp/dhcp6.h"
  20. #include "dhcp/option.h"
  21. #include "dhcp/option6_ia.h"
  22. #include "dhcp/option6_iaaddr.h"
  23. using namespace std;
  24. using namespace isc;
  25. using namespace isc::dhcp;
  26. using namespace isc::asiolink;
  27. namespace {
  28. class Option6IATest : public ::testing::Test {
  29. public:
  30. Option6IATest() {
  31. }
  32. };
  33. TEST_F(Option6IATest, basic) {
  34. boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
  35. for (int i=0; i<128; i++)
  36. simple_buf[i] = 0;
  37. simple_buf[0]=0xa1; // iaid
  38. simple_buf[1]=0xa2;
  39. simple_buf[2]=0xa3;
  40. simple_buf[3]=0xa4;
  41. simple_buf[4]=0x81; // T1
  42. simple_buf[5]=0x02;
  43. simple_buf[6]=0x03;
  44. simple_buf[7]=0x04;
  45. simple_buf[8]=0x84; // T2
  46. simple_buf[9]=0x03;
  47. simple_buf[10]=0x02;
  48. simple_buf[11]=0x01;
  49. // create an option
  50. // unpack() is called from constructor
  51. Option6IA* opt = new Option6IA(D6O_IA_NA,
  52. simple_buf,
  53. 128,
  54. 0,
  55. 12);
  56. EXPECT_EQ(D6O_IA_NA, opt->getType());
  57. EXPECT_EQ(0xa1a2a3a4, opt->getIAID());
  58. EXPECT_EQ(0x81020304, opt->getT1());
  59. EXPECT_EQ(0x84030201, opt->getT2());
  60. // pack this option again in the same buffer, but in
  61. // different place
  62. // test for pack()
  63. int offset = opt->pack(simple_buf, 128, 60);
  64. // 4 bytes header + 4 bytes content
  65. EXPECT_EQ(12, opt->len() - 4);
  66. EXPECT_EQ(D6O_IA_NA, opt->getType());
  67. EXPECT_EQ(offset, 76); // 60 + lenght(IA_NA) = 76
  68. // check if pack worked properly:
  69. // if option type is correct
  70. EXPECT_EQ(D6O_IA_NA, simple_buf[60]*256 + simple_buf[61]);
  71. // if option length is correct
  72. EXPECT_EQ(12, simple_buf[62]*256 + simple_buf[63]);
  73. // if iaid is correct
  74. unsigned int iaid = htonl(*(unsigned int*)&simple_buf[64]);
  75. EXPECT_EQ(0xa1a2a3a4, iaid );
  76. // if T1 is correct
  77. EXPECT_EQ(0x81020304, (simple_buf[68] << 24) +
  78. (simple_buf[69] << 16) +
  79. (simple_buf[70] << 8) +
  80. (simple_buf[71]) );
  81. // if T1 is correct
  82. EXPECT_EQ(0x84030201, (simple_buf[72] << 24) +
  83. (simple_buf[73] << 16) +
  84. (simple_buf[74] << 8) +
  85. (simple_buf[75]) );
  86. delete opt;
  87. }
  88. TEST_F(Option6IATest, simple) {
  89. boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
  90. for (int i=0; i<128; i++)
  91. simple_buf[i] = 0;
  92. Option6IA * ia = new Option6IA(D6O_IA_NA, 1234);
  93. ia->setT1(2345);
  94. ia->setT2(3456);
  95. EXPECT_EQ(D6O_IA_NA, ia->getType());
  96. EXPECT_EQ(1234, ia->getIAID());
  97. EXPECT_EQ(2345, ia->getT1());
  98. EXPECT_EQ(3456, ia->getT2());
  99. delete ia;
  100. }
  101. // test if option can build suboptions
  102. TEST_F(Option6IATest, suboptions_pack) {
  103. boost::shared_array<uint8_t> buf(new uint8_t[128]);
  104. for (int i=0; i<128; i++)
  105. buf[i] = 0;
  106. buf[0] = 0xff;
  107. buf[1] = 0xfe;
  108. buf[2] = 0xfc;
  109. Option6IA * ia = new Option6IA(D6O_IA_NA, 0x13579ace);
  110. ia->setT1(0x2345);
  111. ia->setT2(0x3456);
  112. boost::shared_ptr<Option> sub1(new Option(Option::V6,
  113. 0xcafe));
  114. boost::shared_ptr<Option6IAAddr> addr1(
  115. new Option6IAAddr(D6O_IAADDR, IOAddress("2001:db8:1234:5678::abcd"),
  116. 0x5000, 0x7000));
  117. ia->addOption(sub1);
  118. ia->addOption(addr1);
  119. ASSERT_EQ(28, addr1->len());
  120. ASSERT_EQ(4, sub1->len());
  121. ASSERT_EQ(48, ia->len());
  122. uint8_t expected[] = {
  123. D6O_IA_NA/256, D6O_IA_NA%256, // type
  124. 0, 44, // length
  125. 0x13, 0x57, 0x9a, 0xce, // iaid
  126. 0, 0, 0x23, 0x45, // T1
  127. 0, 0, 0x34, 0x56, // T2
  128. // iaaddr suboption
  129. D6O_IAADDR/256, D6O_IAADDR%256, // type
  130. 0, 24, // len
  131. 0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
  132. 0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
  133. 0, 0, 0x50, 0, // preferred-lifetime
  134. 0, 0, 0x70, 0, // valid-lifetime
  135. // suboption
  136. 0xca, 0xfe, // type
  137. 0, 0 // len
  138. };
  139. int offset = ia->pack(buf, 128, 10);
  140. ASSERT_EQ(offset, 10 + 48);
  141. EXPECT_EQ(0, memcmp(&buf[10], expected, 48));
  142. delete ia;
  143. }
  144. // test if option can parse suboptions
  145. TEST_F(Option6IATest, suboptions_unpack) {
  146. uint8_t expected[] = {
  147. D6O_IA_NA/256, D6O_IA_NA%256, // type
  148. 0, 28, // length
  149. 0x13, 0x57, 0x9a, 0xce, // iaid
  150. 0, 0, 0x23, 0x45, // T1
  151. 0, 0, 0x34, 0x56, // T2
  152. // iaaddr suboption
  153. D6O_IAADDR/256, D6O_IAADDR%256, // type
  154. 0, 24, // len
  155. 0x20, 0x01, 0xd, 0xb8, 0x12,0x34, 0x56, 0x78,
  156. 0, 0, 0, 0, 0, 0, 0xab, 0xcd, // IP address
  157. 0, 0, 0x50, 0, // preferred-lifetime
  158. 0, 0, 0x70, 0, // valid-lifetime
  159. // suboption
  160. 0xca, 0xfe, // type
  161. 0, 0 // len
  162. };
  163. boost::shared_array<uint8_t> buf(new uint8_t[128]);
  164. for (int i=0; i<128; i++)
  165. buf[i] = 0;
  166. memcpy(&buf[0], expected, 48);
  167. Option6IA* ia = 0;
  168. EXPECT_NO_THROW({
  169. ia = new Option6IA(D6O_IA_NA, buf, 128, 4, 44);
  170. cout << "Parsed option:" << endl << ia->toText() << endl;
  171. });
  172. ASSERT_TRUE(ia);
  173. EXPECT_EQ(D6O_IA_NA, ia->getType());
  174. EXPECT_EQ(0x13579ace, ia->getIAID());
  175. EXPECT_EQ(0x2345, ia->getT1());
  176. EXPECT_EQ(0x3456, ia->getT2());
  177. boost::shared_ptr<Option> subopt = ia->getOption(D6O_IAADDR);
  178. ASSERT_NE(boost::shared_ptr<Option>(), subopt); // non-NULL
  179. // checks for address option
  180. Option6IAAddr * addr = dynamic_cast<Option6IAAddr*>(subopt.get());
  181. ASSERT_TRUE(NULL != addr);
  182. EXPECT_EQ(D6O_IAADDR, addr->getType());
  183. EXPECT_EQ(28, addr->len());
  184. EXPECT_EQ(0x5000, addr->getPreferred());
  185. EXPECT_EQ(0x7000, addr->getValid());
  186. EXPECT_EQ("2001:db8:1234:5678::abcd", addr->getAddress().toText());
  187. // checks for dummy option
  188. subopt = ia->getOption(0xcafe);
  189. ASSERT_FALSE(subopt == boost::shared_ptr<Option>()); // non-NULL
  190. EXPECT_EQ(0xcafe, subopt->getType());
  191. EXPECT_EQ(4, subopt->len());
  192. EXPECT_EQ(NULL, subopt->getData());
  193. subopt = ia->getOption(1); // get option 1
  194. ASSERT_EQ(subopt, boost::shared_ptr<Option>()); // NULL
  195. delete ia;
  196. }
  197. }