libdhcp_unittest.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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/libdhcp.h"
  20. #include "config.h"
  21. using namespace std;
  22. using namespace isc;
  23. using namespace isc::dhcp;
  24. namespace {
  25. class LibDhcpTest : public ::testing::Test {
  26. public:
  27. LibDhcpTest() {
  28. }
  29. };
  30. static const uint8_t packed[] = {
  31. 0, 12, 0, 5, 100, 101, 102, 103, 104, // opt1 (9 bytes)
  32. 0, 13, 0, 3, 105, 106, 107, // opt2 (7 bytes)
  33. 0, 14, 0, 2, 108, 109, // opt3 (6 bytes)
  34. 1, 0, 0, 4, 110, 111, 112, 113, // opt4 (8 bytes)
  35. 1, 1, 0, 1, 114 // opt5 (5 bytes)
  36. };
  37. TEST_F(LibDhcpTest, packOptions6) {
  38. boost::shared_array<uint8_t> buf(new uint8_t[512]);
  39. isc::dhcp::Option::Option6Collection opts; // list of options
  40. // generate content for options
  41. for (int i = 0; i < 64; i++) {
  42. buf[i]=i+100;
  43. }
  44. boost::shared_ptr<Option> opt1(new Option(Option::V6, 12, buf, 0, 5));
  45. boost::shared_ptr<Option> opt2(new Option(Option::V6, 13, buf, 5, 3));
  46. boost::shared_ptr<Option> opt3(new Option(Option::V6, 14, buf, 8, 2));
  47. boost::shared_ptr<Option> opt4(new Option(Option::V6,256, buf,10, 4));
  48. boost::shared_ptr<Option> opt5(new Option(Option::V6,257, buf,14, 1));
  49. opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt1));
  50. opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt2));
  51. opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt3));
  52. opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt4));
  53. opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt5));
  54. unsigned int offset;
  55. EXPECT_NO_THROW ({
  56. offset = LibDHCP::packOptions6(buf, 512, 100, opts);
  57. });
  58. EXPECT_EQ(135, offset); // options should take 35 bytes
  59. EXPECT_EQ(0, memcmp(&buf[100], packed, 35) );
  60. }
  61. TEST_F(LibDhcpTest, unpackOptions6) {
  62. // just couple of random options
  63. // Option is used as a simple option implementation
  64. // More advanced uses are validated in tests dedicated for
  65. // specific derived classes.
  66. isc::dhcp::Option::Option6Collection options; // list of options
  67. // we can't use packed directly, as shared_array would try to
  68. // free it eventually
  69. boost::shared_array<uint8_t> buf(new uint8_t[512]);
  70. memcpy(&buf[0], packed, 35);
  71. unsigned int offset;
  72. EXPECT_NO_THROW ({
  73. offset = LibDHCP::unpackOptions6(buf, 512, 0, 35, options);
  74. });
  75. EXPECT_EQ(35, offset); // parsed first 35 bytes (offset 0..34)
  76. EXPECT_EQ(options.size(), 5); // there should be 5 options
  77. isc::dhcp::Option::Option6Collection::const_iterator x = options.find(12);
  78. ASSERT_NE(x, options.end()); // option 1 should exist
  79. EXPECT_EQ(12, x->second->getType()); // this should be option 12
  80. ASSERT_EQ(9, x->second->len()); // it should be of length 9
  81. EXPECT_EQ(0, memcmp(x->second->getData(), packed+4, 5)); // data len=5
  82. x = options.find(13);
  83. ASSERT_NE(x, options.end()); // option 13 should exist
  84. EXPECT_EQ(13, x->second->getType()); // this should be option 13
  85. ASSERT_EQ(7, x->second->len()); // it should be of length 7
  86. EXPECT_EQ(0, memcmp(x->second->getData(), packed+13, 3)); // data len=3
  87. x = options.find(14);
  88. ASSERT_NE(x, options.end()); // option 3 should exist
  89. EXPECT_EQ(14, x->second->getType()); // this should be option 14
  90. ASSERT_EQ(6, x->second->len()); // it should be of length 6
  91. EXPECT_EQ(0, memcmp(x->second->getData(), packed+20, 2)); // data len=2
  92. x = options.find(256);
  93. ASSERT_NE(x, options.end()); // option 256 should exist
  94. EXPECT_EQ(256, x->second->getType()); // this should be option 256
  95. ASSERT_EQ(8, x->second->len()); // it should be of length 7
  96. EXPECT_EQ(0, memcmp(x->second->getData(), packed+26, 4)); // data len=4
  97. x = options.find(257);
  98. ASSERT_NE(x, options.end()); // option 257 should exist
  99. EXPECT_EQ(257, x->second->getType()); // this should be option 257
  100. ASSERT_EQ(5, x->second->len()); // it should be of length 5
  101. EXPECT_EQ(0, memcmp(x->second->getData(), packed+34, 1)); // data len=1
  102. x = options.find(0);
  103. EXPECT_EQ(x, options.end()); // option 0 not found
  104. x = options.find(1); // 1 is htons(256) on little endians. Worth checking
  105. EXPECT_EQ(x, options.end()); // option 1 not found
  106. x = options.find(2);
  107. EXPECT_EQ(x, options.end()); // option 2 not found
  108. x = options.find(32000);
  109. EXPECT_EQ(x, options.end()); // option 32000 not found
  110. }
  111. }