pkt6_unittest.cc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 <asiolink/io_address.h>
  20. #include <dhcp/option.h>
  21. #include <dhcp/pkt6.h>
  22. #include <dhcp/dhcp6.h>
  23. using namespace std;
  24. using namespace isc;
  25. using namespace isc::asiolink;
  26. using namespace isc::dhcp;
  27. namespace {
  28. // empty class for now, but may be extended once Addr6 becomes bigger
  29. class Pkt6Test : public ::testing::Test {
  30. public:
  31. Pkt6Test() {
  32. }
  33. };
  34. TEST_F(Pkt6Test, constructor) {
  35. Pkt6 * pkt1 = new Pkt6(17);
  36. EXPECT_EQ(pkt1->data_len_, 17);
  37. delete pkt1;
  38. }
  39. // captured actual SOLICIT packet: transid=0x3d79fb
  40. // options: client-id, in_na, dns-server, elapsed-time, option-request
  41. // this code is autogenerated (see src/bin/dhcp6/tests/iface_mgr_unittest.c)
  42. Pkt6 *capture1() {
  43. Pkt6* pkt;
  44. pkt = new Pkt6(98);
  45. pkt->remote_port_ = 546;
  46. pkt->remote_addr_ = IOAddress("fe80::21e:8cff:fe9b:7349");
  47. pkt->local_port_ = 0;
  48. pkt->local_addr_ = IOAddress("ff02::1:2");
  49. pkt->ifindex_ = 2;
  50. pkt->iface_ = "eth0";
  51. pkt->data_[0]=1;
  52. pkt->data_[1]=01; pkt->data_[2]=02; pkt->data_[3]=03; pkt->data_[4]=0;
  53. pkt->data_[5]=1; pkt->data_[6]=0; pkt->data_[7]=14; pkt->data_[8]=0;
  54. pkt->data_[9]=1; pkt->data_[10]=0; pkt->data_[11]=1; pkt->data_[12]=21;
  55. pkt->data_[13]=158; pkt->data_[14]=60; pkt->data_[15]=22; pkt->data_[16]=0;
  56. pkt->data_[17]=30; pkt->data_[18]=140; pkt->data_[19]=155; pkt->data_[20]=115;
  57. pkt->data_[21]=73; pkt->data_[22]=0; pkt->data_[23]=3; pkt->data_[24]=0;
  58. pkt->data_[25]=40; pkt->data_[26]=0; pkt->data_[27]=0; pkt->data_[28]=0;
  59. pkt->data_[29]=1; pkt->data_[30]=255; pkt->data_[31]=255; pkt->data_[32]=255;
  60. pkt->data_[33]=255; pkt->data_[34]=255; pkt->data_[35]=255; pkt->data_[36]=255;
  61. pkt->data_[37]=255; pkt->data_[38]=0; pkt->data_[39]=5; pkt->data_[40]=0;
  62. pkt->data_[41]=24; pkt->data_[42]=32; pkt->data_[43]=1; pkt->data_[44]=13;
  63. pkt->data_[45]=184; pkt->data_[46]=0; pkt->data_[47]=1; pkt->data_[48]=0;
  64. pkt->data_[49]=0; pkt->data_[50]=0; pkt->data_[51]=0; pkt->data_[52]=0;
  65. pkt->data_[53]=0; pkt->data_[54]=0; pkt->data_[55]=0; pkt->data_[56]=18;
  66. pkt->data_[57]=52; pkt->data_[58]=255; pkt->data_[59]=255; pkt->data_[60]=255;
  67. pkt->data_[61]=255; pkt->data_[62]=255; pkt->data_[63]=255; pkt->data_[64]=255;
  68. pkt->data_[65]=255; pkt->data_[66]=0; pkt->data_[67]=23; pkt->data_[68]=0;
  69. pkt->data_[69]=16; pkt->data_[70]=32; pkt->data_[71]=1; pkt->data_[72]=13;
  70. pkt->data_[73]=184; pkt->data_[74]=0; pkt->data_[75]=1; pkt->data_[76]=0;
  71. pkt->data_[77]=0; pkt->data_[78]=0; pkt->data_[79]=0; pkt->data_[80]=0;
  72. pkt->data_[81]=0; pkt->data_[82]=0; pkt->data_[83]=0; pkt->data_[84]=221;
  73. pkt->data_[85]=221; pkt->data_[86]=0; pkt->data_[87]=8; pkt->data_[88]=0;
  74. pkt->data_[89]=2; pkt->data_[90]=0; pkt->data_[91]=100; pkt->data_[92]=0;
  75. pkt->data_[93]=6; pkt->data_[94]=0; pkt->data_[95]=2; pkt->data_[96]=0;
  76. pkt->data_[97]=23;
  77. return (pkt);
  78. }
  79. TEST_F(Pkt6Test, unpack_solicit1) {
  80. Pkt6 * sol = capture1();
  81. ASSERT_EQ(true, sol->unpack());
  82. // check for length
  83. EXPECT_EQ(98, sol->len() );
  84. // check for type
  85. EXPECT_EQ(DHCPV6_SOLICIT, sol->getType() );
  86. // check that all present options are returned
  87. EXPECT_TRUE(sol->getOption(D6O_CLIENTID)); // client-id is present
  88. EXPECT_TRUE(sol->getOption(D6O_IA_NA)); // IA_NA is present
  89. EXPECT_TRUE(sol->getOption(D6O_ELAPSED_TIME)); // elapsed is present
  90. EXPECT_TRUE(sol->getOption(D6O_NAME_SERVERS));
  91. EXPECT_TRUE(sol->getOption(D6O_ORO));
  92. // let's check that non-present options are not returned
  93. EXPECT_FALSE(sol->getOption(D6O_SERVERID)); // server-id is missing
  94. EXPECT_FALSE(sol->getOption(D6O_IA_TA));
  95. EXPECT_FALSE(sol->getOption(D6O_IAADDR));
  96. // let's limit verbosity of this test
  97. // std::cout << sol->toText();
  98. delete sol;
  99. }
  100. TEST_F(Pkt6Test, packUnpack) {
  101. Pkt6 * parent = new Pkt6(100);
  102. parent->setType(DHCPV6_SOLICIT);
  103. boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
  104. boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
  105. boost::shared_ptr<Option> opt3(new Option(Option::V6, 100));
  106. // let's not use zero-length option type 3 as it is IA_NA
  107. parent->addOption(opt1);
  108. parent->addOption(opt2);
  109. parent->addOption(opt3);
  110. EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
  111. int transid = parent->getTransid();
  112. // transaction-id was randomized, let's remember it
  113. // calculated length should be 16
  114. EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
  115. parent->len() );
  116. EXPECT_TRUE( parent->pack() );
  117. //
  118. EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
  119. parent->len() );
  120. // let's delete options from options_ collection
  121. // they still be defined in packed
  122. parent->options_.clear();
  123. // that that removed options are indeed are gone
  124. EXPECT_EQ( 4, parent->len() );
  125. // now recreate options list
  126. EXPECT_TRUE( parent->unpack() );
  127. // transid, message-type should be the same as before
  128. EXPECT_EQ(transid, parent->getTransid());
  129. EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
  130. EXPECT_TRUE( parent->getOption(1));
  131. EXPECT_TRUE( parent->getOption(2));
  132. EXPECT_TRUE( parent->getOption(100));
  133. EXPECT_FALSE( parent->getOption(4));
  134. delete parent;
  135. }
  136. TEST_F(Pkt6Test, addGetDelOptions) {
  137. Pkt6 * parent = new Pkt6(100);
  138. boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
  139. boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
  140. boost::shared_ptr<Option> opt3(new Option(Option::V6, 2));
  141. parent->addOption(opt1);
  142. parent->addOption(opt2);
  143. // getOption() test
  144. EXPECT_EQ(opt1, parent->getOption(1));
  145. EXPECT_EQ(opt2, parent->getOption(2));
  146. // expect NULL
  147. EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
  148. // now there are 2 options of type 2
  149. parent->addOption(opt3);
  150. // let's delete one of them
  151. EXPECT_EQ(true, parent->delOption(2));
  152. // there still should be the other option 2
  153. EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
  154. // let's delete the other option 2
  155. EXPECT_EQ(true, parent->delOption(2));
  156. // no more options with type=2
  157. EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(2));
  158. // let's try to delete - should fail
  159. EXPECT_TRUE(false == parent->delOption(2));
  160. delete parent;
  161. }
  162. }