option_unittest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 <boost/shared_ptr.hpp>
  20. #include "dhcp/dhcp6.h"
  21. #include "dhcp/option.h"
  22. using namespace std;
  23. using namespace isc;
  24. using namespace isc::dhcp;
  25. namespace {
  26. class OptionTest : public ::testing::Test {
  27. public:
  28. OptionTest() {
  29. }
  30. };
  31. // v4 is not really implemented yet. A simple test will do for now
  32. TEST_F(OptionTest, basic4) {
  33. Option* opt = new Option(Option::V4, 17);
  34. EXPECT_EQ(17, opt->getType());
  35. EXPECT_EQ(NULL, opt->getData());
  36. EXPECT_EQ(2, opt->len()); // just v4 header
  37. delete opt;
  38. }
  39. // tests simple constructor
  40. TEST_F(OptionTest, basic6) {
  41. Option* opt = new Option(Option::V6, 1);
  42. EXPECT_EQ(1, opt->getType());
  43. EXPECT_EQ(NULL, opt->getData());
  44. EXPECT_EQ(4, opt->len()); // just v6 header
  45. delete opt;
  46. }
  47. // tests contructor used in pkt reception
  48. // option contains actual data
  49. TEST_F(OptionTest, data1) {
  50. boost::shared_array<char> buf(new char[32]);
  51. for (int i=0; i<32; i++)
  52. buf[i] = 100+i;
  53. Option* opt = new Option(Option::V6, 333, //type
  54. buf,
  55. 3, // offset
  56. 7); // 7 bytes of data
  57. EXPECT_EQ(333, opt->getType());
  58. ASSERT_EQ(&buf[3], opt->getData());
  59. ASSERT_EQ(11, opt->len());
  60. EXPECT_EQ(0, memcmp(&buf[3], opt->getData(), 7) );
  61. int offset = opt->pack(buf, 32, 20);
  62. EXPECT_EQ(31, offset);
  63. EXPECT_EQ(buf[20], 333/256); // type
  64. EXPECT_EQ(buf[21], 333%256);
  65. EXPECT_EQ(buf[22], 0); // len
  66. EXPECT_EQ(buf[23], 7);
  67. // payload
  68. EXPECT_EQ(0, memcmp(&buf[3], &buf[24], 7) );
  69. delete opt;
  70. }
  71. // another text that tests the same thing, just
  72. // with different input parameters
  73. TEST_F(OptionTest, data2) {
  74. boost::shared_array<char> simple_buf(new char[128]);
  75. for (int i=0; i<128; i++)
  76. simple_buf[i] = 0;
  77. simple_buf[0]=0xa1;
  78. simple_buf[1]=0xa2;
  79. simple_buf[2]=0xa3;
  80. simple_buf[3]=0xa4;
  81. // create an option (unpack content)
  82. Option* opt = new Option(Option::V6,
  83. D6O_CLIENTID,
  84. simple_buf,
  85. 0,
  86. 4);
  87. // pack this option again in the same buffer, but in
  88. // different place
  89. int offset18 = opt->pack(simple_buf, 128, 10);
  90. // 4 bytes header + 4 bytes content
  91. EXPECT_EQ(8, opt->len());
  92. EXPECT_EQ(D6O_CLIENTID, opt->getType());
  93. EXPECT_EQ(offset18, 18);
  94. // check if pack worked properly:
  95. // if option type is correct
  96. EXPECT_EQ(D6O_CLIENTID, simple_buf[10]*256 + simple_buf[11]);
  97. // if option length is correct
  98. EXPECT_EQ(4, simple_buf[12]*256 + simple_buf[13]);
  99. // if option content is correct
  100. EXPECT_EQ(0, memcmp(&simple_buf[0], &simple_buf[14],4));
  101. delete opt;
  102. }
  103. // check that an option can contain 2 suboptions:
  104. // opt1
  105. // +----opt2
  106. // |
  107. // +----opt3
  108. //
  109. TEST_F(OptionTest, suboptions1) {
  110. boost::shared_array<char> buf(new char[128]);
  111. for (int i=0; i<128; i++)
  112. buf[i] = 100+i;
  113. Option* opt1 = new Option(Option::V6, 65535, //type
  114. buf,
  115. 0, // offset
  116. 3); // 3 bytes of data
  117. boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
  118. boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
  119. buf,
  120. 3, // offset
  121. 5)); // 5 bytes of data
  122. opt1->addOption(opt2);
  123. opt1->addOption(opt3);
  124. // opt2 len = 4 (just header)
  125. // opt3 len = 9 4(header)+5(data)
  126. // opt1 len = 7 + suboptions() = 7 + 4 + 9 = 20
  127. EXPECT_EQ(4, opt2->len());
  128. EXPECT_EQ(9, opt3->len());
  129. EXPECT_EQ(20, opt1->len());
  130. char expected[] = {
  131. 0xff, 0xff, 0, 16, 100, 101, 102,
  132. 0, 7, 0, 5, 103, 104, 105, 106, 107,
  133. 0, 13, 0, 0 // no data at all
  134. };
  135. int offset = opt1->pack(buf, 128, 20);
  136. EXPECT_EQ(40, offset);
  137. // payload
  138. EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
  139. delete opt1;
  140. }
  141. // check that an option can contain 2 suboptions:
  142. // opt1
  143. // +----opt2
  144. // |
  145. // +----opt3
  146. //
  147. TEST_F(OptionTest, suboptions2) {
  148. boost::shared_array<char> buf(new char[128]);
  149. for (int i=0; i<128; i++)
  150. buf[i] = 100+i;
  151. Option* opt1 = new Option(Option::V6, 65535, //type
  152. buf,
  153. 0, // offset
  154. 3); // 3 bytes of data
  155. boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
  156. boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
  157. buf,
  158. 3, // offset
  159. 5)); // 5 bytes of data
  160. opt1->addOption(opt2);
  161. opt2->addOption(opt3);
  162. // opt3 len = 9 4(header)+5(data)
  163. // opt2 len = 4 (just header) + len(opt3)
  164. // opt1 len = 7 + len(opt2)
  165. char expected[] = {
  166. 0xff, 0xff, 0, 16, 100, 101, 102,
  167. 0, 13, 0, 9,
  168. 0, 7, 0, 5, 103, 104, 105, 106, 107,
  169. };
  170. int offset = opt1->pack(buf, 128, 20);
  171. EXPECT_EQ(40, offset);
  172. // payload
  173. EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
  174. delete opt1;
  175. }
  176. }