option6_addrlst_unittest.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 "io_address.h"
  20. #include "dhcp/dhcp6.h"
  21. #include "dhcp/option.h"
  22. #include "dhcp/option6_addrlst.h"
  23. using namespace std;
  24. using namespace isc;
  25. using namespace isc::dhcp;
  26. using namespace isc::asiolink;
  27. namespace {
  28. class Option6AddrLstTest : public ::testing::Test {
  29. public:
  30. Option6AddrLstTest() {
  31. }
  32. };
  33. TEST_F(Option6AddrLstTest, basic) {
  34. // limiting tests to just a 2001:db8::/32 as is *wrong*.
  35. // Good tests check corner cases as well.
  36. // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff checks
  37. // for integer overflow
  38. // ff02::face:b00c checks if multicast addresses
  39. // can be represented properly.
  40. uint8_t sampledata[] = {
  41. // 2001:db8:1::dead:beef
  42. 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
  43. 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
  44. // ff02::face:b00c
  45. 0xff, 02, 0, 0, 0, 0, 0 , 0,
  46. 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
  47. // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
  48. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  49. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  50. };
  51. uint8_t expected1[] = {
  52. D6O_NAME_SERVERS/256, D6O_NAME_SERVERS%256,//type
  53. 0, 16, // len = 16 (1 address)
  54. 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
  55. 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
  56. };
  57. uint8_t expected2[] = {
  58. D6O_SIP_SERVERS_ADDR/256, D6O_SIP_SERVERS_ADDR%256,
  59. 0, 32, // len = 32 (2 addresses)
  60. // 2001:db8:1::dead:beef
  61. 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
  62. 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
  63. // ff02::face:b00c
  64. 0xff, 02, 0, 0, 0, 0, 0 , 0,
  65. 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
  66. // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
  67. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  68. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  69. };
  70. uint8_t expected3[] = {
  71. D6O_NIS_SERVERS/256, D6O_NIS_SERVERS%256,
  72. 0, 48,
  73. // 2001:db8:1::dead:beef
  74. 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
  75. 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
  76. // ff02::face:b00c
  77. 0xff, 02, 0, 0, 0, 0, 0 , 0,
  78. 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
  79. // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
  80. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  81. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  82. };
  83. boost::shared_array<uint8_t> buf(new uint8_t[300]);
  84. for (int i = 0; i < 300; i++)
  85. buf[i] = 0;
  86. memcpy(&buf[0], sampledata, 48);
  87. // just a single address
  88. Option6AddrLst* opt1 = 0;
  89. EXPECT_NO_THROW(
  90. opt1 = new Option6AddrLst(D6O_NAME_SERVERS, buf, 128, 0, 16);
  91. );
  92. EXPECT_EQ(Option::V6, opt1->getUniverse());
  93. EXPECT_EQ(D6O_NAME_SERVERS, opt1->getType());
  94. EXPECT_EQ(20, opt1->len());
  95. Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
  96. ASSERT_EQ(1, addrs.size());
  97. IOAddress addr = addrs[0];
  98. EXPECT_EQ("2001:db8:1::dead:beef", addr.toText());
  99. // pack this option again in the same buffer, but in
  100. // different place
  101. int offset = opt1->pack(buf,300, 100);
  102. EXPECT_EQ(120, offset);
  103. EXPECT_EQ( 0, memcmp(expected1, &buf[100], 20) );
  104. // two addresses
  105. Option6AddrLst* opt2 = 0;
  106. EXPECT_NO_THROW(
  107. opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR, buf, 128, 0, 32);
  108. );
  109. EXPECT_EQ(D6O_SIP_SERVERS_ADDR, opt2->getType());
  110. EXPECT_EQ(36, opt2->len());
  111. addrs = opt2->getAddresses();
  112. ASSERT_EQ(2, addrs.size());
  113. EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
  114. EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
  115. // pack this option again in the same buffer, but in
  116. // different place
  117. offset = opt2->pack(buf,300, 150);
  118. EXPECT_EQ(150+36, offset);
  119. EXPECT_EQ( 0, memcmp(expected2, &buf[150], 36));
  120. // three addresses
  121. Option6AddrLst* opt3 = 0;
  122. EXPECT_NO_THROW(
  123. opt3 = new Option6AddrLst(D6O_NIS_SERVERS, buf, 128, 0, 48);
  124. );
  125. EXPECT_EQ(D6O_NIS_SERVERS, opt3->getType());
  126. EXPECT_EQ(52, opt3->len());
  127. addrs = opt3->getAddresses();
  128. ASSERT_EQ(3, addrs.size());
  129. EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
  130. EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
  131. EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", addrs[2].toText());
  132. // pack this option again in the same buffer, but in
  133. // different place
  134. offset = opt3->pack(buf,300, 200);
  135. EXPECT_EQ(252, offset);
  136. EXPECT_EQ( 0, memcmp(expected3, &buf[200], 52) );
  137. EXPECT_NO_THROW(
  138. delete opt1;
  139. delete opt2;
  140. delete opt3;
  141. );
  142. }
  143. TEST_F(Option6AddrLstTest, constructors) {
  144. Option6AddrLst* opt1 = 0;
  145. EXPECT_NO_THROW(
  146. opt1 = new Option6AddrLst(1234, IOAddress("::1"));
  147. );
  148. EXPECT_EQ(Option::V6, opt1->getUniverse());
  149. EXPECT_EQ(1234, opt1->getType());
  150. Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
  151. ASSERT_EQ(1, addrs.size() );
  152. EXPECT_EQ("::1", addrs[0].toText());
  153. addrs.clear();
  154. addrs.push_back(IOAddress(string("fe80::1234")));
  155. addrs.push_back(IOAddress(string("2001:db8:1::baca")));
  156. Option6AddrLst* opt2 = 0;
  157. EXPECT_NO_THROW(
  158. opt2 = new Option6AddrLst(5678, addrs);
  159. );
  160. Option6AddrLst::AddressContainer check = opt2->getAddresses();
  161. ASSERT_EQ(2, check.size() );
  162. EXPECT_EQ("fe80::1234", check[0].toText());
  163. EXPECT_EQ("2001:db8:1::baca", check[1].toText());
  164. EXPECT_NO_THROW(
  165. delete opt1;
  166. delete opt2;
  167. );
  168. }
  169. TEST_F(Option6AddrLstTest, setAddress) {
  170. Option6AddrLst* opt1 = 0;
  171. EXPECT_NO_THROW(
  172. opt1 = new Option6AddrLst(1234, IOAddress("::1"));
  173. );
  174. opt1->setAddress(IOAddress("2001:db8:1::2"));
  175. /// TODO It used to be ::2 address, but io_address represents
  176. /// it as ::0.0.0.2. Purpose of this test is to verify
  177. /// that setAddress() works, not deal with subtleties of
  178. /// io_address handling of IPv4-mapped IPv6 addresses, we
  179. /// switched to a more common address. User interested
  180. /// in pursuing this matter further is encouraged to look
  181. /// at section 2.5.5 of RFC4291 (and possibly implement
  182. /// a test for IOAddress)
  183. Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
  184. ASSERT_EQ(1, addrs.size() );
  185. EXPECT_EQ("2001:db8:1::2", addrs[0].toText());
  186. EXPECT_NO_THROW(
  187. delete opt1;
  188. );
  189. }
  190. } // namespace