pkt6_unittest.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Copyright (C) 2011-2012 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. uint8_t data[] = { 0, 1, 2, 3, 4, 5 };
  36. Pkt6 * pkt1 = new Pkt6(data, sizeof(data) );
  37. EXPECT_EQ(6, pkt1->getData().size());
  38. EXPECT_EQ(0, memcmp( &pkt1->getData()[0], data, sizeof(data)) );
  39. delete pkt1;
  40. }
  41. // captured actual SOLICIT packet: transid=0x3d79fb
  42. // options: client-id, in_na, dns-server, elapsed-time, option-request
  43. // this code is autogenerated (see src/bin/dhcp6/tests/iface_mgr_unittest.c)
  44. Pkt6 *capture1() {
  45. Pkt6* pkt;
  46. uint8_t data[98];
  47. data[0]=1;
  48. data[1]=01; data[2]=02; data[3]=03; data[4]=0;
  49. data[5]=1; data[6]=0; data[7]=14; data[8]=0;
  50. data[9]=1; data[10]=0; data[11]=1; data[12]=21;
  51. data[13]=158; data[14]=60; data[15]=22; data[16]=0;
  52. data[17]=30; data[18]=140; data[19]=155; data[20]=115;
  53. data[21]=73; data[22]=0; data[23]=3; data[24]=0;
  54. data[25]=40; data[26]=0; data[27]=0; data[28]=0;
  55. data[29]=1; data[30]=255; data[31]=255; data[32]=255;
  56. data[33]=255; data[34]=255; data[35]=255; data[36]=255;
  57. data[37]=255; data[38]=0; data[39]=5; data[40]=0;
  58. data[41]=24; data[42]=32; data[43]=1; data[44]=13;
  59. data[45]=184; data[46]=0; data[47]=1; data[48]=0;
  60. data[49]=0; data[50]=0; data[51]=0; data[52]=0;
  61. data[53]=0; data[54]=0; data[55]=0; data[56]=18;
  62. data[57]=52; data[58]=255; data[59]=255; data[60]=255;
  63. data[61]=255; data[62]=255; data[63]=255; data[64]=255;
  64. data[65]=255; data[66]=0; data[67]=23; data[68]=0;
  65. data[69]=16; data[70]=32; data[71]=1; data[72]=13;
  66. data[73]=184; data[74]=0; data[75]=1; data[76]=0;
  67. data[77]=0; data[78]=0; data[79]=0; data[80]=0;
  68. data[81]=0; data[82]=0; data[83]=0; data[84]=221;
  69. data[85]=221; data[86]=0; data[87]=8; data[88]=0;
  70. data[89]=2; data[90]=0; data[91]=100; data[92]=0;
  71. data[93]=6; data[94]=0; data[95]=2; data[96]=0;
  72. data[97]=23;
  73. pkt = new Pkt6(data, sizeof(data));
  74. pkt->setRemotePort(546);
  75. pkt->setRemoteAddr(IOAddress("fe80::21e:8cff:fe9b:7349"));
  76. pkt->setLocalPort(0);
  77. pkt->setLocalAddr(IOAddress("ff02::1:2"));
  78. pkt->setIndex(2);
  79. pkt->setIface("eth0");
  80. return (pkt);
  81. }
  82. TEST_F(Pkt6Test, unpack_solicit1) {
  83. Pkt6 * sol = capture1();
  84. ASSERT_EQ(true, sol->unpack());
  85. // check for length
  86. EXPECT_EQ(98, sol->len() );
  87. // check for type
  88. EXPECT_EQ(DHCPV6_SOLICIT, sol->getType() );
  89. // check that all present options are returned
  90. EXPECT_TRUE(sol->getOption(D6O_CLIENTID)); // client-id is present
  91. EXPECT_TRUE(sol->getOption(D6O_IA_NA)); // IA_NA is present
  92. EXPECT_TRUE(sol->getOption(D6O_ELAPSED_TIME)); // elapsed is present
  93. EXPECT_TRUE(sol->getOption(D6O_NAME_SERVERS));
  94. EXPECT_TRUE(sol->getOption(D6O_ORO));
  95. // let's check that non-present options are not returned
  96. EXPECT_FALSE(sol->getOption(D6O_SERVERID)); // server-id is missing
  97. EXPECT_FALSE(sol->getOption(D6O_IA_TA));
  98. EXPECT_FALSE(sol->getOption(D6O_IAADDR));
  99. delete sol;
  100. }
  101. TEST_F(Pkt6Test, packUnpack) {
  102. Pkt6* parent = new Pkt6(DHCPV6_SOLICIT, 0x020304);
  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. // calculated length should be 16
  112. EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
  113. parent->len() );
  114. EXPECT_TRUE( parent->pack() );
  115. EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
  116. parent->len() );
  117. // create second packet,based on assembled data from the first one
  118. Pkt6* clone = new Pkt6((const uint8_t*)parent->getBuffer().getData(), parent->getBuffer().getLength());
  119. // now recreate options list
  120. EXPECT_TRUE( clone->unpack() );
  121. // transid, message-type should be the same as before
  122. EXPECT_EQ(parent->getTransid(), parent->getTransid());
  123. EXPECT_EQ(DHCPV6_SOLICIT, clone->getType());
  124. EXPECT_TRUE( clone->getOption(1));
  125. EXPECT_TRUE( clone->getOption(2));
  126. EXPECT_TRUE( clone->getOption(100));
  127. EXPECT_FALSE( clone->getOption(4));
  128. delete parent;
  129. delete clone;
  130. }
  131. TEST_F(Pkt6Test, addGetDelOptions) {
  132. Pkt6 * parent = new Pkt6(DHCPV6_SOLICIT, random() );
  133. boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
  134. boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
  135. boost::shared_ptr<Option> opt3(new Option(Option::V6, 2));
  136. parent->addOption(opt1);
  137. parent->addOption(opt2);
  138. // getOption() test
  139. EXPECT_EQ(opt1, parent->getOption(1));
  140. EXPECT_EQ(opt2, parent->getOption(2));
  141. // expect NULL
  142. EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
  143. // now there are 2 options of type 2
  144. parent->addOption(opt3);
  145. // let's delete one of them
  146. EXPECT_EQ(true, parent->delOption(2));
  147. // there still should be the other option 2
  148. EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
  149. // let's delete the other option 2
  150. EXPECT_EQ(true, parent->delOption(2));
  151. // no more options with type=2
  152. EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(2));
  153. // let's try to delete - should fail
  154. EXPECT_TRUE(false == parent->delOption(2));
  155. delete parent;
  156. }
  157. }