dhcp6_srv_unittest.cc 4.61 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
37
38
39
40
41
42
43
44
45
46
47
48
class NakedDhcpv6Srv: public Dhcpv6Srv {
    // "naked" Interface Manager, exposes internal fields
public:
    NakedDhcpv6Srv() { }

    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
    // there's almost no code now. What's there provides echo capability
57
58
    // that is just a proof of concept and will be removed soon
    // No need to thoroughly test it
59

60
61
62
63
    // 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.
64
65
66
    EXPECT_NO_THROW( {
        Dhcpv6Srv * srv = new Dhcpv6Srv();

67
68
69
70
71
        delete srv;
        });

}

72
73
74
75
76
TEST_F(Dhcpv6SrvTest, Solicit_basic) {
    NakedDhcpv6Srv * srv = 0;
    EXPECT_NO_THROW( srv = new NakedDhcpv6Srv(); );

    // a dummy content for client-id
77
    boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
78
79
    for (int i=0; i<32; i++)
        clntDuid[i] = 100+i;
80
81
82
83
84

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

85
    boost::shared_ptr<Option6IA> ia =
86
        boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, 234));
87
88
89
90
91
92
93
94
95
96
    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);

97
98
99
100
101
102
103
104
105
106
107
108
109
110
    // 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);

111
112
113
114
115
116
117
118
119
    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);
120
    ASSERT_TRUE( tmp );
121
122

    Option6IA * reply_ia = dynamic_cast<Option6IA*> ( tmp.get() );
123
124
125
126
127
128
129
130
131
132
    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() );
133

134
    EXPECT_TRUE( clientid->getData() == tmp->getData() );
135

136
137
138
139
    // 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() );
140

141
    EXPECT_TRUE(tmp->getData() == srv->getServerID()->getData());
142
143
144
145

    // more checks to be implemented
    delete srv;

146
}
147

148
}