dhcp6_srv_unittest.cc 4.55 KB
Newer Older
1
// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8 9 10 11 12 13 14
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

15 16 17 18 19
#include <config.h>
#include <iostream>
#include <sstream>

#include <arpa/inet.h>
20 21
#include <gtest/gtest.h>

22
#include "dhcp/dhcp6.h"
23
#include "dhcp6/dhcp6_srv.h"
24
#include "dhcp/option6_ia.h"
25 26 27

using namespace std;
using namespace isc;
28 29 30 31 32
using namespace isc::dhcp;

// namespace has to be named, because friends are defined in Dhcpv6Srv class
// Maybe it should be isc::test?
namespace test {
33

34 35 36
class NakedDhcpv6Srv: public Dhcpv6Srv {
    // "naked" Interface Manager, exposes internal fields
public:
37
    NakedDhcpv6Srv():Dhcpv6Srv(DHCP6_SERVER_PORT + 10000) { }
38 39 40 41 42 43 44 45 46 47 48

    boost::shared_ptr<Pkt6>
    processSolicit(boost::shared_ptr<Pkt6>& request) {
        return Dhcpv6Srv::processSolicit(request);
    }
    boost::shared_ptr<Pkt6>
    processRequest(boost::shared_ptr<Pkt6>& request) {
        return Dhcpv6Srv::processRequest(request);
    }
};

49 50 51 52 53
class Dhcpv6SrvTest : public ::testing::Test {
public:
    Dhcpv6SrvTest() {
    }
};
54

55
TEST_F(Dhcpv6SrvTest, basic) {
56 57 58 59
    // srv has stubbed interface detection. It will read
    // interfaces.txt instead. It will pretend to have detected
    // fe80::1234 link-local address on eth0 interface. Obviously
    // an attempt to bind this socket will fail.
60
    Dhcpv6Srv* srv = NULL;
61
    ASSERT_NO_THROW( {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
62 63 64
        // open an unpriviledged port
        srv = new Dhcpv6Srv(DHCP6_SERVER_PORT + 10000);
    });
65

66
    delete srv;
67 68
}

69
TEST_F(Dhcpv6SrvTest, Solicit_basic) {
70
    NakedDhcpv6Srv* srv = NULL;
71
    ASSERT_NO_THROW( srv = new NakedDhcpv6Srv(); );
72 73

    // a dummy content for client-id
74
    boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
Tomek Mrugalski's avatar
Tomek Mrugalski committed
75
    for (int i = 0; i < 32; i++)
76
        clntDuid[i] = 100 + i;
77 78 79 80 81

    boost::shared_ptr<Pkt6> sol =
        boost::shared_ptr<Pkt6>(new Pkt6(DHCPV6_SOLICIT,
                                         1234, Pkt6::UDP));

82
    boost::shared_ptr<Option6IA> ia =
83
        boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, 234));
84 85 86 87 88 89 90 91 92 93
    ia->setT1(1501);
    ia->setT2(2601);
    sol->addOption(ia);

    // Let's not send address in solicit yet
    // boost::shared_ptr<Option6IAAddr> addr(new Option6IAAddr(D6O_IAADDR,
    //    IOAddress("2001:db8:1234:ffff::ffff"), 5001, 7001));
    // ia->addOption(addr);
    // sol->addOption(ia);

94 95 96 97 98 99 100 101 102 103 104 105 106 107
    // constructed very simple SOLICIT message with:
    // - client-id option (mandatory)
    // - IA option (a request for address, without any addresses)

    // expected returned ADVERTISE message:
    // - copy of client-id
    // - server-id
    // - IA that includes IAADDR

    boost::shared_ptr<Option> clientid =
        boost::shared_ptr<Option>(new Option(Option::V6, D6O_CLIENTID,
                                             clntDuid, 0, 16));
    sol->addOption(clientid);

108 109 110 111 112 113 114 115 116
    boost::shared_ptr<Pkt6> reply = srv->processSolicit(sol);

    // check if we get response at all
    ASSERT_TRUE( reply != boost::shared_ptr<Pkt6>() );

    EXPECT_EQ( DHCPV6_ADVERTISE, reply->getType() );
    EXPECT_EQ( 1234, reply->getTransid() );

    boost::shared_ptr<Option> tmp = reply->getOption(D6O_IA_NA);
117
    ASSERT_TRUE( tmp );
118

119
    Option6IA* reply_ia = dynamic_cast<Option6IA*> ( tmp.get() );
120 121 122 123 124 125 126 127 128 129
    EXPECT_EQ( 234, reply_ia->getIAID() );

    // check that there's an address included
    EXPECT_TRUE( reply_ia->getOption(D6O_IAADDR));

    // check that server included our own client-id
    tmp = reply->getOption(D6O_CLIENTID);
    ASSERT_TRUE( tmp );
    EXPECT_EQ(clientid->getType(), tmp->getType() );
    ASSERT_EQ(clientid->len(), tmp->len() );
130

131
    EXPECT_TRUE( clientid->getData() == tmp->getData() );
132

133 134 135 136
    // check that server included its server-id
    tmp = reply->getOption(D6O_SERVERID);
    EXPECT_EQ(tmp->getType(), srv->getServerID()->getType() );
    ASSERT_EQ(tmp->len(),  srv->getServerID()->len() );
137

138
    EXPECT_TRUE(tmp->getData() == srv->getServerID()->getData());
139 140 141 142

    // more checks to be implemented
    delete srv;

143
}
144

145
}