123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- // Copyright (C) 2011-2015 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 <asiolink/io_address.h>
- #include <dhcp/dhcp6.h>
- #include <dhcp/option.h>
- #include <dhcp/option6_addrlst.h>
- #include <util/buffer.h>
- #include <gtest/gtest.h>
- #include <boost/scoped_ptr.hpp>
- #include <iostream>
- #include <sstream>
- #include <arpa/inet.h>
- using namespace std;
- using namespace isc;
- using namespace isc::dhcp;
- using namespace isc::asiolink;
- using namespace isc::util;
- using boost::scoped_ptr;
- namespace {
- class Option6AddrLstTest : public ::testing::Test {
- public:
- Option6AddrLstTest(): buf_(255), outBuf_(255) {
- for (unsigned i = 0; i < 255; i++) {
- buf_[i] = 255 - i;
- }
- }
- OptionBuffer buf_;
- OutputBuffer outBuf_;
- };
- TEST_F(Option6AddrLstTest, basic) {
- // Limiting tests to just a 2001:db8::/32 is *wrong*.
- // Good tests check corner cases as well.
- // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff checks
- // for integer overflow.
- // ff02::face:b00c checks if multicast addresses
- // can be represented properly.
- uint8_t sampledata[] = {
- // 2001:db8:1::dead:beef
- 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
- 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
- // ff02::face:b00c
- 0xff, 02, 0, 0, 0, 0, 0 , 0,
- 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
- // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
- uint8_t expected1[] = {
- D6O_NAME_SERVERS/256, D6O_NAME_SERVERS%256,//type
- 0, 16, // len = 16 (1 address)
- 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
- 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
- };
- uint8_t expected2[] = {
- D6O_SIP_SERVERS_ADDR/256, D6O_SIP_SERVERS_ADDR%256,
- 0, 32, // len = 32 (2 addresses)
- // 2001:db8:1::dead:beef
- 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
- 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
- // ff02::face:b00c
- 0xff, 02, 0, 0, 0, 0, 0 , 0,
- 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
- // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
- uint8_t expected3[] = {
- D6O_NIS_SERVERS/256, D6O_NIS_SERVERS%256,
- 0, 48,
- // 2001:db8:1::dead:beef
- 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0, 0,
- 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef,
- // ff02::face:b00c
- 0xff, 02, 0, 0, 0, 0, 0 , 0,
- 0, 0, 0, 0, 0xfa, 0xce, 0xb0, 0x0c,
- // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
- memcpy(&buf_[0], sampledata, 48);
- // Just a single address
- scoped_ptr<Option6AddrLst> opt1;
- EXPECT_NO_THROW(
- opt1.reset(new Option6AddrLst(D6O_NAME_SERVERS,
- buf_.begin(), buf_.begin() + 16));
- );
- EXPECT_EQ(Option::V6, opt1->getUniverse());
- EXPECT_EQ(D6O_NAME_SERVERS, opt1->getType());
- EXPECT_EQ(20, opt1->len());
- Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
- ASSERT_EQ(1, addrs.size());
- IOAddress addr = addrs[0];
- EXPECT_EQ("2001:db8:1::dead:beef", addr.toText());
- // Pack this option
- opt1->pack(outBuf_);
- EXPECT_EQ(20, outBuf_.getLength());
- EXPECT_EQ(0, memcmp(expected1, outBuf_.getData(), 20));
- // Two addresses
- scoped_ptr<Option6AddrLst> opt2;
- EXPECT_NO_THROW(
- opt2.reset(new Option6AddrLst(D6O_SIP_SERVERS_ADDR,
- buf_.begin(), buf_.begin() + 32));
- );
- EXPECT_EQ(D6O_SIP_SERVERS_ADDR, opt2->getType());
- EXPECT_EQ(36, opt2->len());
- addrs = opt2->getAddresses();
- ASSERT_EQ(2, addrs.size());
- EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
- EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
- // Pack this option
- outBuf_.clear();
- opt2->pack(outBuf_);
- EXPECT_EQ(36, outBuf_.getLength() );
- EXPECT_EQ(0, memcmp(expected2, outBuf_.getData(), 36));
- // Three addresses
- scoped_ptr<Option6AddrLst> opt3;
- EXPECT_NO_THROW(
- opt3.reset(new Option6AddrLst(D6O_NIS_SERVERS,
- buf_.begin(), buf_.begin() + 48));
- );
- EXPECT_EQ(D6O_NIS_SERVERS, opt3->getType());
- EXPECT_EQ(52, opt3->len());
- addrs = opt3->getAddresses();
- ASSERT_EQ(3, addrs.size());
- EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
- EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", addrs[2].toText());
- // Pack this option
- outBuf_.clear();
- opt3->pack(outBuf_);
- EXPECT_EQ(52, outBuf_.getLength());
- EXPECT_EQ(0, memcmp(expected3, outBuf_.getData(), 52));
- EXPECT_NO_THROW(opt1.reset());
- EXPECT_NO_THROW(opt2.reset());
- EXPECT_NO_THROW(opt3.reset());
- }
- TEST_F(Option6AddrLstTest, constructors) {
- scoped_ptr<Option6AddrLst> opt1;
- EXPECT_NO_THROW(
- opt1.reset(new Option6AddrLst(1234, IOAddress("::1")));
- );
- EXPECT_EQ(Option::V6, opt1->getUniverse());
- EXPECT_EQ(1234, opt1->getType());
- Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
- ASSERT_EQ(1, addrs.size() );
- EXPECT_EQ("::1", addrs[0].toText());
- addrs.clear();
- addrs.push_back(IOAddress(string("fe80::1234")));
- addrs.push_back(IOAddress(string("2001:db8:1::baca")));
- scoped_ptr<Option6AddrLst> opt2;
- EXPECT_NO_THROW(
- opt2.reset(new Option6AddrLst(5678, addrs));
- );
- Option6AddrLst::AddressContainer check = opt2->getAddresses();
- ASSERT_EQ(2, check.size() );
- EXPECT_EQ("fe80::1234", check[0].toText());
- EXPECT_EQ("2001:db8:1::baca", check[1].toText());
- EXPECT_NO_THROW(opt1.reset());
- EXPECT_NO_THROW(opt2.reset());
- }
- TEST_F(Option6AddrLstTest, setAddress) {
- scoped_ptr<Option6AddrLst> opt1;
- EXPECT_NO_THROW(
- opt1.reset(new Option6AddrLst(1234, IOAddress("::1")));
- );
- opt1->setAddress(IOAddress("2001:db8:1::2"));
- /// TODO It used to be ::2 address, but io_address represents
- /// it as ::0.0.0.2. Purpose of this test is to verify
- /// that setAddress() works, not deal with subtleties of
- /// io_address handling of IPv4-mapped IPv6 addresses, we
- /// switched to a more common address. User interested
- /// in pursuing this matter further is encouraged to look
- /// at section 2.5.5 of RFC4291 (and possibly implement
- /// a test for IOAddress)
- Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
- ASSERT_EQ(1, addrs.size());
- EXPECT_EQ("2001:db8:1::2", addrs[0].toText());
- EXPECT_NO_THROW(opt1.reset());
- }
- // This test checks that the option holding IPv6 address list can
- // be converted to textual format.
- TEST_F(Option6AddrLstTest, toText) {
- Option6AddrLst opt(1234, IOAddress("2001:db8:1::1"));
- // Generate a few IPv6 addresses.
- Option6AddrLst::AddressContainer addresses;
- for (int i = 2; i < 6; ++i) {
- std::stringstream s;
- s << "2001:db8:1::" << i;
- addresses.push_back(IOAddress(s.str()));
- }
- opt.setAddresses(addresses);
- EXPECT_EQ("type=01234, len=00064: 2001:db8:1::2 2001:db8:1::3 "
- "2001:db8:1::4 2001:db8:1::5", opt.toText());
- }
- } // namespace
|