123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
- //
- // 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.
- #include <config.h>
- #include <iostream>
- #include <sstream>
- #include <arpa/inet.h>
- #include <gtest/gtest.h>
- #include <asiolink/io_address.h>
- #include <dhcp/option.h>
- #include <dhcp/pkt6.h>
- #include <dhcp/dhcp6.h>
- using namespace std;
- using namespace isc;
- using namespace isc::asiolink;
- using namespace isc::dhcp;
- namespace {
- // empty class for now, but may be extended once Addr6 becomes bigger
- class Pkt6Test : public ::testing::Test {
- public:
- Pkt6Test() {
- }
- };
- TEST_F(Pkt6Test, constructor) {
- uint8_t data[] = { 0, 1, 2, 3, 4, 5 };
- Pkt6 * pkt1 = new Pkt6(data, sizeof(data) );
- EXPECT_EQ(6, pkt1->getData().size());
- EXPECT_EQ(0, memcmp( &pkt1->getData()[0], data, sizeof(data)) );
- delete pkt1;
- }
- // captured actual SOLICIT packet: transid=0x3d79fb
- // options: client-id, in_na, dns-server, elapsed-time, option-request
- // this code is autogenerated (see src/bin/dhcp6/tests/iface_mgr_unittest.c)
- Pkt6 *capture1() {
- Pkt6* pkt;
- uint8_t data[98];
- data[0]=1;
- data[1]=01; data[2]=02; data[3]=03; data[4]=0;
- data[5]=1; data[6]=0; data[7]=14; data[8]=0;
- data[9]=1; data[10]=0; data[11]=1; data[12]=21;
- data[13]=158; data[14]=60; data[15]=22; data[16]=0;
- data[17]=30; data[18]=140; data[19]=155; data[20]=115;
- data[21]=73; data[22]=0; data[23]=3; data[24]=0;
- data[25]=40; data[26]=0; data[27]=0; data[28]=0;
- data[29]=1; data[30]=255; data[31]=255; data[32]=255;
- data[33]=255; data[34]=255; data[35]=255; data[36]=255;
- data[37]=255; data[38]=0; data[39]=5; data[40]=0;
- data[41]=24; data[42]=32; data[43]=1; data[44]=13;
- data[45]=184; data[46]=0; data[47]=1; data[48]=0;
- data[49]=0; data[50]=0; data[51]=0; data[52]=0;
- data[53]=0; data[54]=0; data[55]=0; data[56]=18;
- data[57]=52; data[58]=255; data[59]=255; data[60]=255;
- data[61]=255; data[62]=255; data[63]=255; data[64]=255;
- data[65]=255; data[66]=0; data[67]=23; data[68]=0;
- data[69]=16; data[70]=32; data[71]=1; data[72]=13;
- data[73]=184; data[74]=0; data[75]=1; data[76]=0;
- data[77]=0; data[78]=0; data[79]=0; data[80]=0;
- data[81]=0; data[82]=0; data[83]=0; data[84]=221;
- data[85]=221; data[86]=0; data[87]=8; data[88]=0;
- data[89]=2; data[90]=0; data[91]=100; data[92]=0;
- data[93]=6; data[94]=0; data[95]=2; data[96]=0;
- data[97]=23;
- pkt = new Pkt6(data, sizeof(data));
- pkt->setRemotePort(546);
- pkt->setRemoteAddr(IOAddress("fe80::21e:8cff:fe9b:7349"));
- pkt->setLocalPort(0);
- pkt->setLocalAddr(IOAddress("ff02::1:2"));
- pkt->setIndex(2);
- pkt->setIface("eth0");
- return (pkt);
- }
- TEST_F(Pkt6Test, unpack_solicit1) {
- Pkt6 * sol = capture1();
- ASSERT_EQ(true, sol->unpack());
- // check for length
- EXPECT_EQ(98, sol->len() );
- // check for type
- EXPECT_EQ(DHCPV6_SOLICIT, sol->getType() );
- // check that all present options are returned
- EXPECT_TRUE(sol->getOption(D6O_CLIENTID)); // client-id is present
- EXPECT_TRUE(sol->getOption(D6O_IA_NA)); // IA_NA is present
- EXPECT_TRUE(sol->getOption(D6O_ELAPSED_TIME)); // elapsed is present
- EXPECT_TRUE(sol->getOption(D6O_NAME_SERVERS));
- EXPECT_TRUE(sol->getOption(D6O_ORO));
- // let's check that non-present options are not returned
- EXPECT_FALSE(sol->getOption(D6O_SERVERID)); // server-id is missing
- EXPECT_FALSE(sol->getOption(D6O_IA_TA));
- EXPECT_FALSE(sol->getOption(D6O_IAADDR));
- delete sol;
- }
- TEST_F(Pkt6Test, packUnpack) {
- Pkt6* parent = new Pkt6(DHCPV6_SOLICIT, 0x020304);
- boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 100));
- // let's not use zero-length option type 3 as it is IA_NA
- parent->addOption(opt1);
- parent->addOption(opt2);
- parent->addOption(opt3);
- EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
- // calculated length should be 16
- EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
- parent->len() );
- EXPECT_TRUE( parent->pack() );
- EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
- parent->len() );
- // create second packet,based on assembled data from the first one
- Pkt6* clone = new Pkt6((const uint8_t*)parent->getBuffer().getData(), parent->getBuffer().getLength());
- // now recreate options list
- EXPECT_TRUE( clone->unpack() );
- // transid, message-type should be the same as before
- EXPECT_EQ(parent->getTransid(), parent->getTransid());
- EXPECT_EQ(DHCPV6_SOLICIT, clone->getType());
- EXPECT_TRUE( clone->getOption(1));
- EXPECT_TRUE( clone->getOption(2));
- EXPECT_TRUE( clone->getOption(100));
- EXPECT_FALSE( clone->getOption(4));
- delete parent;
- delete clone;
- }
- TEST_F(Pkt6Test, addGetDelOptions) {
- Pkt6 * parent = new Pkt6(DHCPV6_SOLICIT, random() );
- boost::shared_ptr<Option> opt1(new Option(Option::V6, 1));
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 2));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 2));
- parent->addOption(opt1);
- parent->addOption(opt2);
- // getOption() test
- EXPECT_EQ(opt1, parent->getOption(1));
- EXPECT_EQ(opt2, parent->getOption(2));
- // expect NULL
- EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
- // now there are 2 options of type 2
- parent->addOption(opt3);
- // let's delete one of them
- EXPECT_EQ(true, parent->delOption(2));
- // there still should be the other option 2
- EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
- // let's delete the other option 2
- EXPECT_EQ(true, parent->delOption(2));
- // no more options with type=2
- EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(2));
- // let's try to delete - should fail
- EXPECT_TRUE(false == parent->delOption(2));
- delete parent;
- }
- }
|