dhcp6_srv_unittest.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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/dhcp6.h"
  20. #include "dhcp6/dhcp6_srv.h"
  21. #include "dhcp/option6_ia.h"
  22. using namespace std;
  23. using namespace isc;
  24. using namespace isc::dhcp;
  25. // namespace has to be named, because friends are defined in Dhcpv6Srv class
  26. // Maybe it should be isc::test?
  27. namespace test {
  28. class NakedDhcpv6Srv: public Dhcpv6Srv {
  29. // "naked" Interface Manager, exposes internal fields
  30. public:
  31. NakedDhcpv6Srv():Dhcpv6Srv(DHCP6_SERVER_PORT + 10000) { }
  32. boost::shared_ptr<Pkt6>
  33. processSolicit(boost::shared_ptr<Pkt6>& request) {
  34. return Dhcpv6Srv::processSolicit(request);
  35. }
  36. boost::shared_ptr<Pkt6>
  37. processRequest(boost::shared_ptr<Pkt6>& request) {
  38. return Dhcpv6Srv::processRequest(request);
  39. }
  40. };
  41. class Dhcpv6SrvTest : public ::testing::Test {
  42. public:
  43. Dhcpv6SrvTest() {
  44. }
  45. };
  46. TEST_F(Dhcpv6SrvTest, basic) {
  47. // srv has stubbed interface detection. It will read
  48. // interfaces.txt instead. It will pretend to have detected
  49. // fe80::1234 link-local address on eth0 interface. Obviously
  50. // an attempt to bind this socket will fail.
  51. Dhcpv6Srv* srv = NULL;
  52. ASSERT_NO_THROW( {
  53. // open an unpriviledged port
  54. srv = new Dhcpv6Srv(DHCP6_SERVER_PORT + 10000);
  55. });
  56. delete srv;
  57. }
  58. TEST_F(Dhcpv6SrvTest, Solicit_basic) {
  59. NakedDhcpv6Srv* srv = NULL;
  60. ASSERT_NO_THROW( srv = new NakedDhcpv6Srv(); );
  61. // a dummy content for client-id
  62. boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
  63. for (int i = 0; i < 32; i++)
  64. clntDuid[i] = 100 + i;
  65. boost::shared_ptr<Pkt6> sol =
  66. boost::shared_ptr<Pkt6>(new Pkt6(DHCPV6_SOLICIT,
  67. 1234, Pkt6::UDP));
  68. boost::shared_ptr<Option6IA> ia =
  69. boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, 234));
  70. ia->setT1(1501);
  71. ia->setT2(2601);
  72. sol->addOption(ia);
  73. // Let's not send address in solicit yet
  74. // boost::shared_ptr<Option6IAAddr> addr(new Option6IAAddr(D6O_IAADDR,
  75. // IOAddress("2001:db8:1234:ffff::ffff"), 5001, 7001));
  76. // ia->addOption(addr);
  77. // sol->addOption(ia);
  78. // constructed very simple SOLICIT message with:
  79. // - client-id option (mandatory)
  80. // - IA option (a request for address, without any addresses)
  81. // expected returned ADVERTISE message:
  82. // - copy of client-id
  83. // - server-id
  84. // - IA that includes IAADDR
  85. boost::shared_ptr<Option> clientid =
  86. boost::shared_ptr<Option>(new Option(Option::V6, D6O_CLIENTID,
  87. clntDuid, 0, 16));
  88. sol->addOption(clientid);
  89. boost::shared_ptr<Pkt6> reply = srv->processSolicit(sol);
  90. // check if we get response at all
  91. ASSERT_TRUE( reply != boost::shared_ptr<Pkt6>() );
  92. EXPECT_EQ( DHCPV6_ADVERTISE, reply->getType() );
  93. EXPECT_EQ( 1234, reply->getTransid() );
  94. boost::shared_ptr<Option> tmp = reply->getOption(D6O_IA_NA);
  95. ASSERT_TRUE( tmp );
  96. Option6IA* reply_ia = dynamic_cast<Option6IA*> ( tmp.get() );
  97. EXPECT_EQ( 234, reply_ia->getIAID() );
  98. // check that there's an address included
  99. EXPECT_TRUE( reply_ia->getOption(D6O_IAADDR));
  100. // check that server included our own client-id
  101. tmp = reply->getOption(D6O_CLIENTID);
  102. ASSERT_TRUE( tmp );
  103. EXPECT_EQ(clientid->getType(), tmp->getType() );
  104. ASSERT_EQ(clientid->len(), tmp->len() );
  105. EXPECT_TRUE( clientid->getData() == tmp->getData() );
  106. // check that server included its server-id
  107. tmp = reply->getOption(D6O_SERVERID);
  108. EXPECT_EQ(tmp->getType(), srv->getServerID()->getType() );
  109. ASSERT_EQ(tmp->len(), srv->getServerID()->len() );
  110. EXPECT_TRUE(tmp->getData() == srv->getServerID()->getData());
  111. // more checks to be implemented
  112. delete srv;
  113. }
  114. }