BIND 10 trac1540, updated. 219324e66e5bf33fde5cd53dc19f82fb1d442fc8 [1540] Huge (29 files changed) Option6 and Pkt6 refactoring in DHCP.
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Feb 3 15:55:09 UTC 2012
The branch, trac1540 has been updated
via 219324e66e5bf33fde5cd53dc19f82fb1d442fc8 (commit)
from 03effee3f28d0b3958f5e7e745b30cb47f6e0e74 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 219324e66e5bf33fde5cd53dc19f82fb1d442fc8
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Fri Feb 3 16:54:41 2012 +0100
[1540] Huge (29 files changed) Option6 and Pkt6 refactoring in DHCP.
- Migrated from boost::shared_array to std::vector<uint8>
- Pkt6 now have all fields private, getters/setters implemented
- Many smaller clean-ups
- Tests updated to follow new procedure
- isc::util::OutputBuffer is now used
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 6 +
src/bin/dhcp4/dhcp4_srv.cc | 56 +++----
src/bin/dhcp4/dhcp4_srv.h | 31 ++---
src/bin/dhcp6/dhcp6_srv.cc | 90 ++++-------
src/bin/dhcp6/dhcp6_srv.h | 42 ++----
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 14 +-
src/lib/dhcp/iface_mgr.cc | 150 ++++++++----------
src/lib/dhcp/libdhcp++.cc | 109 ++++++-------
src/lib/dhcp/libdhcp++.h | 67 ++++-----
src/lib/dhcp/option.cc | 132 ++++------------
src/lib/dhcp/option.h | 143 +++++------------
src/lib/dhcp/option4_addrlst.cc | 7 +-
src/lib/dhcp/option4_addrlst.h | 15 +-
src/lib/dhcp/option6_addrlst.cc | 60 ++-----
src/lib/dhcp/option6_addrlst.h | 45 ++----
src/lib/dhcp/option6_ia.cc | 81 +++-------
src/lib/dhcp/option6_ia.h | 64 +++-----
src/lib/dhcp/option6_iaaddr.cc | 66 +++-----
src/lib/dhcp/option6_iaaddr.h | 46 ++----
src/lib/dhcp/pkt4.h | 79 ++++-----
src/lib/dhcp/pkt6.cc | 122 ++++++---------
src/lib/dhcp/pkt6.h | 193 ++++++++++++++++------
src/lib/dhcp/tests/iface_mgr_unittest.cc | 39 +++--
src/lib/dhcp/tests/libdhcp++_unittest.cc | 61 ++++----
src/lib/dhcp/tests/option6_addrlst_unittest.cc | 52 +++---
src/lib/dhcp/tests/option6_ia_unittest.cc | 123 ++++++---------
src/lib/dhcp/tests/option6_iaaddr_unittest.cc | 87 ++++++-----
src/lib/dhcp/tests/option_unittest.cc | 201 +++++++++++-------------
src/lib/dhcp/tests/pkt6_unittest.cc | 122 +++++++--------
src/lib/util/buffer.h | 11 ++
30 files changed, 989 insertions(+), 1325 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index a1bfb8a..e09ab6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+3XX. [func] tomek
+ libdhcp++: Option6 and Pkt6 now follow the same design as
+ options and packet for DHCPv4. General code refactoring after
+ end of 2011 year release.
+ (Trac #1540, git TBD)
+
359. [bug] kevin
Corrected SOA serial check in xfrout. It now compares the SOA
serial of an IXFR query with that of the server based serial
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index 89b48c6..735c39f 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -59,8 +59,8 @@ Dhcpv4Srv::~Dhcpv4Srv() {
bool
Dhcpv4Srv::run() {
while (!shutdown_) {
- boost::shared_ptr<Pkt4> query; // client's message
- boost::shared_ptr<Pkt4> rsp; // server's response
+ Pkt4Ptr query; // client's message
+ Pkt4Ptr rsp; // server's response
query = IfaceMgr::instance().receive4();
@@ -141,14 +141,13 @@ Dhcpv4Srv::setServerID() {
#if 0
// uncomment this once ticket 1350 is merged.
IOAddress srvId("127.0.0.1");
- serverid_ = boost::shared_ptr<Option>(
+ serverid_ = OptionPtr(
new Option4AddrLst(Option::V4, DHO_DHCP_SERVER_IDENTIFIER, srvId));
#endif
}
-void Dhcpv4Srv::copyDefaultFields(const boost::shared_ptr<Pkt4>& question,
- boost::shared_ptr<Pkt4>& answer) {
+void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
answer->setIface(question->getIface());
answer->setIndex(question->getIndex());
answer->setCiaddr(question->getCiaddr());
@@ -174,17 +173,17 @@ void Dhcpv4Srv::copyDefaultFields(const boost::shared_ptr<Pkt4>& question,
}
-void Dhcpv4Srv::appendDefaultOptions(boost::shared_ptr<Pkt4>& msg, uint8_t msg_type) {
- boost::shared_ptr<Option> opt;
+void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
+ OptionPtr opt;
// add Message Type Option (type 53)
std::vector<uint8_t> tmp;
tmp.push_back(static_cast<uint8_t>(msg_type));
- opt = boost::shared_ptr<Option>(new Option(Option::V4, DHO_DHCP_MESSAGE_TYPE, tmp));
+ opt = OptionPtr(new Option(Option::V4, DHO_DHCP_MESSAGE_TYPE, tmp));
msg->addOption(opt);
// DHCP Server Identifier (type 54)
- opt = boost::shared_ptr<Option>
+ opt = OptionPtr
(new Option4AddrLst(DHO_DHCP_SERVER_IDENTIFIER, IOAddress(HARDCODED_SERVER_ID)));
msg->addOption(opt);
@@ -192,47 +191,43 @@ void Dhcpv4Srv::appendDefaultOptions(boost::shared_ptr<Pkt4>& msg, uint8_t msg_t
}
-void Dhcpv4Srv::appendRequestedOptions(boost::shared_ptr<Pkt4>& msg) {
- boost::shared_ptr<Option> opt;
+void Dhcpv4Srv::appendRequestedOptions(Pkt4Ptr& msg) {
+ OptionPtr opt;
// Domain name (type 15)
vector<uint8_t> domain(HARDCODED_DOMAIN_NAME.begin(), HARDCODED_DOMAIN_NAME.end());
- opt = boost::shared_ptr<Option>(new Option(Option::V4, DHO_DOMAIN_NAME, domain));
+ opt = OptionPtr(new Option(Option::V4, DHO_DOMAIN_NAME, domain));
msg->addOption(opt);
// TODO: Add Option_String class
// DNS servers (type 6)
- opt = boost::shared_ptr<Option>
- (new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS, IOAddress(HARDCODED_DNS_SERVER)));
+ opt = OptionPtr(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS, IOAddress(HARDCODED_DNS_SERVER)));
msg->addOption(opt);
}
-void Dhcpv4Srv::tryAssignLease(boost::shared_ptr<Pkt4>& msg) {
- boost::shared_ptr<Option> opt;
+void Dhcpv4Srv::tryAssignLease(Pkt4Ptr& msg) {
+ OptionPtr opt;
// TODO: Implement actual lease assignment here
msg->setYiaddr(IOAddress(HARDCODED_LEASE));
// IP Address Lease time (type 51)
- opt = boost::shared_ptr<Option>(new Option(Option::V4, DHO_DHCP_LEASE_TIME));
+ opt = OptionPtr(new Option(Option::V4, DHO_DHCP_LEASE_TIME));
opt->setUint32(HARDCODED_LEASE_TIME);
msg->addOption(opt);
// TODO: create Option_IntArray that holds list of integers, similar to Option4_AddrLst
// Subnet mask (type 1)
- opt = boost::shared_ptr<Option>
- (new Option4AddrLst(DHO_SUBNET_MASK, IOAddress(HARDCODED_NETMASK)));
+ opt = OptionPtr(new Option4AddrLst(DHO_SUBNET_MASK, IOAddress(HARDCODED_NETMASK)));
msg->addOption(opt);
// Router (type 3)
- opt = boost::shared_ptr<Option>
- (new Option4AddrLst(DHO_ROUTERS, IOAddress(HARDCODED_GATEWAY)));
+ opt = OptionPtr(new Option4AddrLst(DHO_ROUTERS, IOAddress(HARDCODED_GATEWAY)));
msg->addOption(opt);
}
-boost::shared_ptr<Pkt4>
-Dhcpv4Srv::processDiscover(boost::shared_ptr<Pkt4>& discover) {
- boost::shared_ptr<Pkt4> offer = boost::shared_ptr<Pkt4>
+Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
+ Pkt4Ptr offer = Pkt4Ptr
(new Pkt4(DHCPOFFER, discover->getTransid()));
copyDefaultFields(discover, offer);
@@ -244,9 +239,8 @@ Dhcpv4Srv::processDiscover(boost::shared_ptr<Pkt4>& discover) {
return (offer);
}
-boost::shared_ptr<Pkt4>
-Dhcpv4Srv::processRequest(boost::shared_ptr<Pkt4>& request) {
- boost::shared_ptr<Pkt4> ack = boost::shared_ptr<Pkt4>
+Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
+ Pkt4Ptr ack = Pkt4Ptr
(new Pkt4(DHCPACK, request->getTransid()));
copyDefaultFields(request, ack);
@@ -258,17 +252,17 @@ Dhcpv4Srv::processRequest(boost::shared_ptr<Pkt4>& request) {
return (ack);
}
-void Dhcpv4Srv::processRelease(boost::shared_ptr<Pkt4>& release) {
+void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
/// TODO: Implement this.
cout << "Received RELEASE on " << release->getIface() << " interface." << endl;
}
-void Dhcpv4Srv::processDecline(boost::shared_ptr<Pkt4>& decline) {
+void Dhcpv4Srv::processDecline(Pkt4Ptr& decline) {
/// TODO: Implement this.
cout << "Received DECLINE on " << decline->getIface() << " interface." << endl;
}
-boost::shared_ptr<Pkt4> Dhcpv4Srv::processInform(boost::shared_ptr<Pkt4>& inform) {
+Pkt4Ptr Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
/// TODO: Currently implemented echo mode. Implement this for real
return (inform);
}
diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h
index cd46977..9be1276 100644
--- a/src/bin/dhcp4/dhcp4_srv.h
+++ b/src/bin/dhcp4/dhcp4_srv.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -15,7 +15,6 @@
#ifndef DHCPV4_SRV_H
#define DHCPV4_SRV_H
-#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
@@ -71,8 +70,7 @@ protected:
/// @param solicit DISCOVER message received from client
///
/// @return OFFER message or NULL
- boost::shared_ptr<Pkt4>
- processDiscover(boost::shared_ptr<Pkt4>& discover);
+ Pkt4Ptr processDiscover(Pkt4Ptr& discover);
/// @brief Processes incoming REQUEST and returns REPLY response.
///
@@ -86,7 +84,7 @@ protected:
/// @param request a message received from client
///
/// @return ACK or NACK message
- boost::shared_ptr<Pkt4> processRequest(boost::shared_ptr<Pkt4>& request);
+ Pkt4Ptr processRequest(Pkt4Ptr& request);
/// @brief Stub function that will handle incoming RELEASE messages.
///
@@ -94,17 +92,17 @@ protected:
/// this function does not return anything.
///
/// @param release message received from client
- void processRelease(boost::shared_ptr<Pkt4>& release);
+ void processRelease(Pkt4Ptr& release);
/// @brief Stub function that will handle incoming DHCPDECLINE messages.
///
/// @param decline message received from client
- void processDecline(boost::shared_ptr<Pkt4>& decline);
+ void processDecline(Pkt4Ptr& decline);
/// @brief Stub function that will handle incoming INFORM messages.
///
/// @param infRequest message received from client
- boost::shared_ptr<Pkt4> processInform(boost::shared_ptr<Pkt4>& inform);
+ Pkt4Ptr processInform(Pkt4Ptr& inform);
/// @brief Copies default parameters from client's to server's message
///
@@ -113,9 +111,7 @@ protected:
///
/// @param question any message sent by client
/// @param answer any message server is going to send as response
- void copyDefaultFields(const boost::shared_ptr<Pkt4>& question,
- boost::shared_ptr<Pkt4>& answer);
-
+ void copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer);
/// @brief Appends options requested by client.
///
@@ -123,8 +119,7 @@ protected:
/// (sent in PRL) or are enforced by server.
///
/// @param msg outgoing message (options will be added here)
- void appendRequestedOptions(boost::shared_ptr<Pkt4>& msg);
-
+ void appendRequestedOptions(Pkt4Ptr& msg);
/// @brief Assigns a lease and appends corresponding options
///
@@ -136,20 +131,18 @@ protected:
/// used fixed, hardcoded lease.
///
/// @param msg OFFER or ACK message (lease options will be added here)
- void tryAssignLease(boost::shared_ptr<Pkt4>& msg);
-
+ void tryAssignLease(Pkt4Ptr& msg);
/// @brief Appends default options to a message
///
/// @param msg message object (options will be added to it)
/// @param msg_type specifies message type
- void appendDefaultOptions(boost::shared_ptr<Pkt4>& msg, uint8_t msg_type);
+ void appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type);
/// @brief Returns server-intentifier option
///
/// @return server-id option
- boost::shared_ptr<isc::dhcp::Option>
- getServerID() { return serverid_; }
+ OptionPtr getServerID() { return serverid_; }
/// @brief Sets server-identifier.
///
@@ -163,7 +156,7 @@ protected:
void setServerID();
/// server DUID (to be sent in server-identifier option)
- boost::shared_ptr<isc::dhcp::Option> serverid_;
+ OptionPtr serverid_;
/// indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 4e69f05..b2bd5f5 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -70,8 +70,8 @@ Dhcpv6Srv::~Dhcpv6Srv() {
bool
Dhcpv6Srv::run() {
while (!shutdown) {
- boost::shared_ptr<Pkt6> query; // client's message
- boost::shared_ptr<Pkt6> rsp; // server's response
+ Pkt6Ptr query; // client's message
+ Pkt6Ptr rsp; // server's response
query = IfaceMgr::instance().receive6();
@@ -110,16 +110,16 @@ Dhcpv6Srv::run() {
<< query->getType() << endl;
}
- cout << "Received " << query->data_len_ << " bytes packet type="
+ cout << "Received " << query->getBuffer().getLength() << " bytes packet type="
<< query->getType() << endl;
cout << query->toText();
if (rsp) {
- rsp->remote_addr_ = query->remote_addr_;
- rsp->local_addr_ = query->local_addr_;
- rsp->remote_port_ = DHCP6_CLIENT_PORT;
- rsp->local_port_ = DHCP6_SERVER_PORT;
- rsp->ifindex_ = query->ifindex_;
- rsp->iface_ = query->iface_;
+ rsp->setRemoteAddr(query->getRemoteAddr());
+ rsp->setLocalAddr(query->getLocalAddr());
+ rsp->setRemotePort(DHCP6_CLIENT_PORT);
+ rsp->setLocalPort(DHCP6_SERVER_PORT);
+ rsp->setIndex(query->getIndex());
+ rsp->setIface(query->getIface());
cout << "Replying with:" << rsp->getType() << endl;
cout << rsp->toText();
cout << "----" << endl;
@@ -143,7 +143,7 @@ Dhcpv6Srv::setServerID() {
/// TODO implement this for real once interface detection is done.
/// Use hardcoded server-id for now
- boost::shared_array<uint8_t> srvid(new uint8_t[14]);
+ OptionBuffer srvid(14);
srvid[0] = 0;
srvid[1] = 1; // DUID type 1 = DUID-LLT (see section 9.2 of RFC3315)
srvid[2] = 0;
@@ -154,12 +154,11 @@ Dhcpv6Srv::setServerID() {
}
serverid_ = boost::shared_ptr<Option>(new Option(Option::V6,
D6O_SERVERID,
- srvid,
- 0, 14));
+ srvid.begin(),
+ srvid.end()));
}
-void Dhcpv6Srv::copyDefaultOptions(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer) {
+void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
// add client-id
boost::shared_ptr<Option> clientid = question->getOption(D6O_CLIENTID);
if (clientid) {
@@ -169,8 +168,7 @@ void Dhcpv6Srv::copyDefaultOptions(const boost::shared_ptr<Pkt6>& question,
// TODO: Should throw if there is no client-id (except anonymous INF-REQUEST)
}
-void Dhcpv6Srv::appendDefaultOptions(const boost::shared_ptr<Pkt6>& /*question*/,
- boost::shared_ptr<Pkt6>& answer) {
+void Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& /*question*/, Pkt6Ptr& answer) {
// TODO: question is currently unused, but we need it at least to know
// message type we are answering
@@ -179,8 +177,7 @@ void Dhcpv6Srv::appendDefaultOptions(const boost::shared_ptr<Pkt6>& /*question*/
}
-void Dhcpv6Srv::appendRequestedOptions(const boost::shared_ptr<Pkt6>& /*question*/,
- boost::shared_ptr<Pkt6>& answer) {
+void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& /*question*/, Pkt6Ptr& answer) {
// TODO: question is currently unused, but we need to extract ORO from it
// and act on its content. Now we just send DNS-SERVERS option.
@@ -190,8 +187,7 @@ void Dhcpv6Srv::appendRequestedOptions(const boost::shared_ptr<Pkt6>& /*question
answer->addOption(dnsservers);
}
-void Dhcpv6Srv::assignLeases(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer) {
+void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
/// TODO Rewrite this once LeaseManager is implemented.
// answer client's IA (this is mostly a dummy,
@@ -217,11 +213,9 @@ void Dhcpv6Srv::assignLeases(const boost::shared_ptr<Pkt6>& question,
}
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processSolicit(const boost::shared_ptr<Pkt6>& solicit) {
+Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
- boost::shared_ptr<Pkt6> advertise(new Pkt6(DHCPV6_ADVERTISE,
- solicit->getTransid()));
+ Pkt6Ptr advertise(new Pkt6(DHCPV6_ADVERTISE, solicit->getTransid()));
copyDefaultOptions(solicit, advertise);
appendDefaultOptions(solicit, advertise);
@@ -232,11 +226,9 @@ Dhcpv6Srv::processSolicit(const boost::shared_ptr<Pkt6>& solicit) {
return (advertise);
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processRequest(const boost::shared_ptr<Pkt6>& request) {
+Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- request->getTransid()));
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, request->getTransid()));
copyDefaultOptions(request, reply);
appendDefaultOptions(request, reply);
@@ -247,50 +239,34 @@ Dhcpv6Srv::processRequest(const boost::shared_ptr<Pkt6>& request) {
return (reply);
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processRenew(const boost::shared_ptr<Pkt6>& renew) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- renew->getTransid(),
- Pkt6::UDP));
+Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, renew->getTransid()));
return reply;
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processRebind(const boost::shared_ptr<Pkt6>& rebind) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
+Pkt6Ptr Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY,
rebind->getTransid(),
Pkt6::UDP));
return reply;
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processConfirm(const boost::shared_ptr<Pkt6>& confirm) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- confirm->getTransid(),
- Pkt6::UDP));
+Pkt6Ptr Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, confirm->getTransid()));
return reply;
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processRelease(const boost::shared_ptr<Pkt6>& release) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- release->getTransid(),
- Pkt6::UDP));
+Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, release->getTransid()));
return reply;
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processDecline(const boost::shared_ptr<Pkt6>& decline) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- decline->getTransid(),
- Pkt6::UDP));
+Pkt6Ptr Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid()));
return reply;
}
-boost::shared_ptr<Pkt6>
-Dhcpv6Srv::processInfRequest(const boost::shared_ptr<Pkt6>& infRequest) {
- boost::shared_ptr<Pkt6> reply(new Pkt6(DHCPV6_REPLY,
- infRequest->getTransid(),
- Pkt6::UDP));
+Pkt6Ptr Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
+ Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
return reply;
}
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index 44a9f8a..1c137cb 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -15,7 +15,6 @@
#ifndef DHCPV6_SRV_H
#define DHCPV6_SRV_H
-#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <dhcp/dhcp6.h>
#include <dhcp/pkt6.h>
@@ -52,8 +51,7 @@ public:
/// @brief Returns server-intentifier option
///
/// @return server-id option
- boost::shared_ptr<isc::dhcp::Option>
- getServerID() { return serverid_; }
+ OptionPtr getServerID() { return serverid_; }
/// @brief Main server processing loop.
///
@@ -80,8 +78,7 @@ protected:
/// @param solicit SOLICIT message received from client
///
/// @return ADVERTISE, REPLY message or NULL
- boost::shared_ptr<Pkt6>
- processSolicit(const boost::shared_ptr<Pkt6>& solicit);
+ Pkt6Ptr processSolicit(const Pkt6Ptr& solicit);
/// @brief Processes incoming REQUEST and returns REPLY response.
///
@@ -94,44 +91,37 @@ protected:
/// @param request a message received from client
///
/// @return REPLY message or NULL
- boost::shared_ptr<Pkt6>
- processRequest(const boost::shared_ptr<Pkt6>& request);
+ Pkt6Ptr processRequest(const Pkt6Ptr& request);
/// @brief Stub function that will handle incoming RENEW messages.
///
/// @param renew message received from client
- boost::shared_ptr<Pkt6>
- processRenew(const boost::shared_ptr<Pkt6>& renew);
+ Pkt6Ptr processRenew(const Pkt6Ptr& renew);
/// @brief Stub function that will handle incoming REBIND messages.
///
/// @param rebind message received from client
- boost::shared_ptr<Pkt6>
- processRebind(const boost::shared_ptr<Pkt6>& rebind);
+ Pkt6Ptr processRebind(const Pkt6Ptr& rebind);
/// @brief Stub function that will handle incoming CONFIRM messages.
///
/// @param confirm message received from client
- boost::shared_ptr<Pkt6>
- processConfirm(const boost::shared_ptr<Pkt6>& confirm);
+ Pkt6Ptr processConfirm(const Pkt6Ptr& confirm);
/// @brief Stub function that will handle incoming RELEASE messages.
///
/// @param release message received from client
- boost::shared_ptr<Pkt6>
- processRelease(const boost::shared_ptr<Pkt6>& release);
+ Pkt6Ptr processRelease(const Pkt6Ptr& release);
/// @brief Stub function that will handle incoming DECLINE messages.
///
/// @param decline message received from client
- boost::shared_ptr<Pkt6>
- processDecline(const boost::shared_ptr<Pkt6>& decline);
+ Pkt6Ptr processDecline(const Pkt6Ptr& decline);
/// @brief Stub function that will handle incoming INF-REQUEST messages.
///
/// @param infRequest message received from client
- boost::shared_ptr<Pkt6>
- processInfRequest(const boost::shared_ptr<Pkt6>& infRequest);
+ Pkt6Ptr processInfRequest(const Pkt6Ptr& infRequest);
/// @brief Copies required options from client message to server answer
///
@@ -141,8 +131,7 @@ protected:
///
/// @param question client's message (options will be copied from here)
/// @param answer server's message (options will be copied here)
- void copyDefaultOptions(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer);
+ void copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
/// @brief Appends default options to server's answer.
///
@@ -152,8 +141,7 @@ protected:
///
/// @param question client's message
/// @param answer server's message (options will be added here)
- void appendDefaultOptions(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer);
+ void appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
/// @brief Appends requested options to server's answer.
///
@@ -163,8 +151,7 @@ protected:
///
/// @param question client's message
/// @param answer server's message (options will be added here)
- void appendRequestedOptions(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer);
+ void appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer);
/// @brief Assigns leases.
///
@@ -174,8 +161,7 @@ protected:
///
/// @param question client's message (with requested IA_NA)
/// @param answer server's message (IA_NA options will be added here)
- void assignLeases(const boost::shared_ptr<Pkt6>& question,
- boost::shared_ptr<Pkt6>& answer);
+ void assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer);
/// @brief Sets server-identifier.
///
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 09d1cec..33267a1 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -84,13 +84,11 @@ TEST_F(Dhcpv6SrvTest, Solicit_basic) {
ASSERT_NO_THROW( srv = new NakedDhcpv6Srv(); );
// a dummy content for client-id
- boost::shared_array<uint8_t> clntDuid(new uint8_t[32]);
+ OptionBuffer clntDuid(32);
for (int i = 0; i < 32; i++)
clntDuid[i] = 100 + i;
- boost::shared_ptr<Pkt6> sol =
- boost::shared_ptr<Pkt6>(new Pkt6(DHCPV6_SOLICIT,
- 1234, Pkt6::UDP));
+ Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234, Pkt6::UDP));
boost::shared_ptr<Option6IA> ia =
boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, 234));
@@ -113,9 +111,9 @@ TEST_F(Dhcpv6SrvTest, Solicit_basic) {
// - server-id
// - IA that includes IAADDR
- boost::shared_ptr<Option> clientid =
- boost::shared_ptr<Option>(new Option(Option::V6, D6O_CLIENTID,
- clntDuid, 0, 16));
+ OptionPtr clientid = OptionPtr(new Option(Option::V6, D6O_CLIENTID,
+ clntDuid.begin(),
+ clntDuid.begin()+16));
sol->addOption(clientid);
boost::shared_ptr<Pkt6> reply = srv->processSolicit(sol);
@@ -126,7 +124,7 @@ TEST_F(Dhcpv6SrvTest, Solicit_basic) {
EXPECT_EQ( DHCPV6_ADVERTISE, reply->getType() );
EXPECT_EQ( 1234, reply->getTransid() );
- boost::shared_ptr<Option> tmp = reply->getOption(D6O_IA_NA);
+ OptionPtr tmp = reply->getOption(D6O_IA_NA);
ASSERT_TRUE( tmp );
Option6IA* reply_ia = dynamic_cast<Option6IA*>(tmp.get());
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index 363b77b..7b9d490 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -437,8 +437,8 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
isc_throw(Unexpected, "Failed to create UDP6 socket.");
}
- /* Set the REUSEADDR option so that we don't fail to start if
- we're being restarted. */
+ // Set the REUSEADDR option so that we don't fail to start if
+ // we're being restarted.
int flag = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&flag, sizeof(flag)) < 0) {
@@ -452,14 +452,14 @@ int IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, int port) {
<< "/port=" << port);
}
#ifdef IPV6_RECVPKTINFO
- /* RFC3542 - a new way */
+ // RFC3542 - a new way
if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO,
&flag, sizeof(flag)) != 0) {
close(sock);
isc_throw(Unexpected, "setsockopt: IPV6_RECVPKTINFO failed.");
}
#else
- /* RFC2292 - an old way */
+ // RFC2292 - an old way
if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO,
&flag, sizeof(flag)) != 0) {
close(sock);
@@ -523,10 +523,10 @@ IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
struct in6_pktinfo *pktinfo;
struct cmsghdr *cmsg;
- Iface* iface = getIface(pkt->iface_);
+ Iface* iface = getIface(pkt->getIface());
if (!iface) {
isc_throw(BadValue, "Unable to send Pkt6. Invalid interface ("
- << pkt->iface_ << ") specified.");
+ << pkt->getIface() << ") specified.");
}
memset(&control_buf_[0], 0, control_buf_len_);
@@ -538,11 +538,11 @@ IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
sockaddr_in6 to;
memset(&to, 0, sizeof(to));
to.sin6_family = AF_INET6;
- to.sin6_port = htons(pkt->remote_port_);
+ to.sin6_port = htons(pkt->getRemotePort());
memcpy(&to.sin6_addr,
- pkt->remote_addr_.getAddress().to_v6().to_bytes().data(),
+ pkt->getRemoteAddr().getAddress().to_v6().to_bytes().data(),
16);
- to.sin6_scope_id = pkt->ifindex_;
+ to.sin6_scope_id = pkt->getIndex();
m.msg_name = &to;
m.msg_namelen = sizeof(to);
@@ -550,8 +550,8 @@ IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
// Set the data buffer we're sending. (Using this wacky
// "scatter-gather" stuff... we only have a single chunk
// of data to send, so we declare a single vector entry.)
- v.iov_base = (char *) &pkt->data_[0];
- v.iov_len = pkt->data_len_;
+ v.iov_base = (char *) pkt->getBuffer().getData();
+ v.iov_len = pkt->getBuffer().getLength();
m.msg_iov = &v;
m.msg_iovlen = 1;
@@ -569,17 +569,17 @@ IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
cmsg->cmsg_len = CMSG_LEN(sizeof(*pktinfo));
pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
memset(pktinfo, 0, sizeof(*pktinfo));
- pktinfo->ipi6_ifindex = pkt->ifindex_;
+ pktinfo->ipi6_ifindex = pkt->getIndex();
m.msg_controllen = cmsg->cmsg_len;
result = sendmsg(getSocket(*pkt), &m, 0);
if (result < 0) {
isc_throw(Unexpected, "Pkt6 send failed: sendmsg() returned " << result);
}
- cout << "Sent " << pkt->data_len_ << " bytes over socket " << getSocket(*pkt)
+ cout << "Sent " << pkt->getBuffer().getLength() << " bytes over socket " << getSocket(*pkt)
<< " on " << iface->getFullName() << " interface: "
- << " dst=[" << pkt->remote_addr_.toText() << "]:" << pkt->remote_port_
- << ", src=" << pkt->local_addr_.toText() << "]:" << pkt->remote_port_
+ << " dst=[" << pkt->getRemoteAddr().toText() << "]:" << pkt->getRemotePort()
+ << ", src=" << pkt->getLocalAddr().toText() << "]:" << pkt->getLocalPort()
<< endl;
return (result);
@@ -813,8 +813,7 @@ IfaceMgr::receive4() {
return (pkt);
}
-boost::shared_ptr<Pkt6>
-IfaceMgr::receive6() {
+Pkt6Ptr IfaceMgr::receive6() {
struct msghdr m;
struct iovec v;
int result;
@@ -822,57 +821,43 @@ IfaceMgr::receive6() {
struct in6_pktinfo* pktinfo;
struct sockaddr_in6 from;
struct in6_addr to_addr;
- boost::shared_ptr<Pkt6> pkt;
- char addr_str[INET6_ADDRSTRLEN];
-
- try {
- // RFC3315 states that server responses may be
- // fragmented if they are over MTU. There is no
- // text whether client's packets may be larger
- // than 1500. Nevertheless to be on the safe side
- // we use larger buffer. This buffer limit is checked
- // during reception (see iov_len below), so we are
- // safe
- pkt = boost::shared_ptr<Pkt6>(new Pkt6(65536));
- } catch (const std::exception& ex) {
- cout << "Failed to create new packet." << endl;
- return (boost::shared_ptr<Pkt6>()); // NULL
- }
+ int ifindex;
+ Pkt6Ptr pkt;
+
+ // RFC3315 states that server responses may be
+ // fragmented if they are over MTU. There is no
+ // text whether client's packets may be larger
+ // than 1500. For now, we can assume that
+ // we don't support packets larger than 1500.
+ const uint32_t RCVBUFSIZE = 1500;
+ static uint8_t buf[RCVBUFSIZE];
memset(&control_buf_[0], 0, control_buf_len_);
memset(&from, 0, sizeof(from));
memset(&to_addr, 0, sizeof(to_addr));
- /*
- * Initialize our message header structure.
- */
+ // Initialize our message header structure.
memset(&m, 0, sizeof(m));
- /*
- * Point so we can get the from address.
- */
+ // Point so we can get the from address.
m.msg_name = &from;
m.msg_namelen = sizeof(from);
- /*
- * Set the data buffer we're receiving. (Using this wacky
- * "scatter-gather" stuff... but we that doesn't really make
- * sense for us, so we use a single vector entry.)
- */
- v.iov_base = (void*)&pkt->data_[0];
- v.iov_len = pkt->data_len_;
+ // Set the data buffer we're receiving. (Using this wacky
+ // "scatter-gather" stuff... but we that doesn't really make
+ // sense for us, so we use a single vector entry.)
+ v.iov_base = (void*)buf;
+ v.iov_len = RCVBUFSIZE;
m.msg_iov = &v;
m.msg_iovlen = 1;
- /*
- * Getting the interface is a bit more involved.
- *
- * We set up some space for a "control message". We have
- * previously asked the kernel to give us packet
- * information (when we initialized the interface), so we
- * should get the destination address from that.
- */
+ // Getting the interface is a bit more involved.
+ //
+ // We set up some space for a "control message". We have
+ // previously asked the kernel to give us packet
+ // information (when we initialized the interface), so we
+ // should get the destination address from that.
m.msg_control = &control_buf_[0];
m.msg_controllen = control_buf_len_;
@@ -917,14 +902,12 @@ IfaceMgr::receive6() {
result = recvmsg(candidate->sockfd_, &m, 0);
if (result >= 0) {
- /*
- * If we did read successfully, then we need to loop
- * through the control messages we received and
- * find the one with our destination address.
- *
- * We also keep a flag to see if we found it. If we
- * didn't, then we consider this to be an error.
- */
+ // If we did read successfully, then we need to loop
+ // through the control messages we received and
+ // find the one with our destination address.
+ //
+ // We also keep a flag to see if we found it. If we
+ // didn't, then we consider this to be an error.
int found_pktinfo = 0;
cmsg = CMSG_FIRSTHDR(&m);
while (cmsg != NULL) {
@@ -932,7 +915,7 @@ IfaceMgr::receive6() {
(cmsg->cmsg_type == IPV6_PKTINFO)) {
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
to_addr = pktinfo->ipi6_addr;
- pkt->ifindex_ = pktinfo->ipi6_ifindex;
+ ifindex = pktinfo->ipi6_ifindex;
found_pktinfo = 1;
}
cmsg = CMSG_NXTHDR(&m, cmsg);
@@ -946,34 +929,35 @@ IfaceMgr::receive6() {
return (boost::shared_ptr<Pkt6>()); // NULL
}
- // That's ugly.
- // TODO add IOAddress constructor that will take struct in6_addr*
- // TODO: there's from_bytes() method added in IOAddress. Use it!
- inet_ntop(AF_INET6, &to_addr, addr_str,INET6_ADDRSTRLEN);
- pkt->local_addr_ = IOAddress(string(addr_str));
- // TODO: there's from_bytes() method added in IOAddress. Use it!
- inet_ntop(AF_INET6, &from.sin6_addr, addr_str, INET6_ADDRSTRLEN);
- pkt->remote_addr_ = IOAddress(string(addr_str));
+ try {
+ pkt = Pkt6Ptr(new Pkt6(buf, result));
+ } catch (const std::exception& ex) {
+ cout << "Failed to create new packet." << endl;
+ return (boost::shared_ptr<Pkt6>()); // NULL
+ }
+
+ pkt->setLocalAddr(IOAddress::from_bytes(AF_INET6, (const uint8_t*)&to_addr));
+ pkt->setRemoteAddr(IOAddress::from_bytes(AF_INET6, (const uint8_t*)&from.sin6_addr));
+
+ pkt->setRemotePort(ntohs(from.sin6_port));
- pkt->remote_port_ = ntohs(from.sin6_port);
+ pkt->setIndex(ifindex);
- Iface* received = getIface(pkt->ifindex_);
+ Iface* received = getIface(pkt->getIndex());
if (received) {
- pkt->iface_ = received->getName();
+ pkt->setIface(received->getName());
} else {
cout << "Received packet over unknown interface (ifindex="
- << pkt->ifindex_ << ")." << endl;
+ << pkt->getIndex() << ")." << endl;
return (boost::shared_ptr<Pkt6>()); // NULL
}
- pkt->data_len_ = result;
-
// TODO Move this to LOG_DEBUG
- cout << "Received " << pkt->data_len_ << " bytes over "
- << pkt->iface_ << "/" << pkt->ifindex_ << " interface: "
- << " src=" << pkt->remote_addr_.toText()
- << ", dst=" << pkt->local_addr_.toText()
+ cout << "Received " << pkt->getBuffer().getLength() << " bytes over "
+ << pkt->getIface() << "/" << pkt->getIndex() << " interface: "
+ << " src=" << pkt->getRemoteAddr().toText()
+ << ", dst=" << pkt->getLocalAddr().toText()
<< endl;
return (pkt);
@@ -981,10 +965,10 @@ IfaceMgr::receive6() {
uint16_t
IfaceMgr::getSocket(isc::dhcp::Pkt6 const& pkt) {
- Iface* iface = getIface(pkt.iface_);
+ Iface* iface = getIface(pkt.getIface());
if (!iface) {
isc_throw(BadValue, "Tried to find socket for non-existent interface "
- << pkt.iface_);
+ << pkt.getIface());
}
SocketCollection::const_iterator s;
diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc
index 801c136..9a4f4de 100644
--- a/src/lib/dhcp/libdhcp++.cc
+++ b/src/lib/dhcp/libdhcp++.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -28,19 +28,16 @@ using namespace isc::dhcp;
using namespace isc::util;
// static array with factories for options
+std::map<unsigned short, Option::Factory*> LibDHCP::v4factories_;
+
+// static array with factories for options
std::map<unsigned short, Option::Factory*> LibDHCP::v6factories_;
-unsigned int
-LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
- unsigned int buf_len,
- unsigned int offset, unsigned int parse_len,
- isc::dhcp::Option::OptionCollection& options) {
- if (offset + parse_len > buf_len) {
- isc_throw(OutOfRange, "Option parse failed. Tried to parse "
- << parse_len << " bytes at offset " << offset
- << ": out of buffer");
- }
- unsigned int end = offset + parse_len;
+
+uint32_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
+ isc::dhcp::Option::OptionCollection& options) {
+ uint32_t offset = 0;
+ unsigned int end = buf.size();
while (offset +4 <= end) {
uint16_t opt_type = buf[offset]*256 + buf[offset+1];
@@ -52,29 +49,27 @@ LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
cout << "Option " << opt_type << " truncated." << endl;
return (offset);
}
- boost::shared_ptr<Option> opt;
+ OptionPtr opt;
switch (opt_type) {
case D6O_IA_NA:
case D6O_IA_PD:
// cout << "Creating Option6IA" << endl;
- opt = boost::shared_ptr<Option>(new Option6IA(opt_type,
- buf, buf_len,
- offset,
- opt_len));
+ opt = OptionPtr(new Option6IA(opt_type,
+ buf.begin() + offset,
+ buf.begin() + offset + opt_len));
break;
case D6O_IAADDR:
// cout << "Creating Option6IAAddr" << endl;
- opt = boost::shared_ptr<Option>(new Option6IAAddr(opt_type,
- buf, buf_len,
- offset, opt_len));
+ opt = OptionPtr(new Option6IAAddr(opt_type,
+ buf.begin() + offset,
+ buf.begin() + offset + opt_len));
break;
default:
// cout << "Creating Option" << endl;
- opt = boost::shared_ptr<Option>(new Option(Option::V6,
- opt_type,
- buf,
- offset,
- opt_len));
+ opt = OptionPtr(new Option(Option::V6,
+ opt_type,
+ buf.begin() + offset,
+ buf.begin() + offset + opt_len));
break;
}
// add option to options
@@ -85,9 +80,8 @@ LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
return (offset);
}
-void
-LibDHCP::unpackOptions4(const std::vector<uint8_t>& buf,
- isc::dhcp::Option::OptionCollection& options) {
+uint32_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
+ isc::dhcp::Option::OptionCollection& options) {
size_t offset = 0;
// 2 - header of DHCPv4 option
@@ -95,11 +89,11 @@ LibDHCP::unpackOptions4(const std::vector<uint8_t>& buf,
uint8_t opt_type = buf[offset++];
if (opt_type == DHO_END)
- return; // just return. Don't need to add DHO_END option
+ return (offset); // just return. Don't need to add DHO_END option
if (offset + 1 >= buf.size()) {
- isc_throw(OutOfRange, "Attempt to parse truncated option "
- << opt_type);
+ isc_throw(OutOfRange, "Attempt to parse truncated option "
+ << opt_type);
}
uint8_t opt_len = buf[offset++];
@@ -109,41 +103,32 @@ LibDHCP::unpackOptions4(const std::vector<uint8_t>& buf,
<< "-byte long buffer.");
}
- boost::shared_ptr<Option> opt;
+ OptionPtr opt;
switch(opt_type) {
default:
- opt = boost::shared_ptr<Option>(new Option(Option::V4, opt_type,
- buf.begin()+offset,
- buf.begin()+offset+opt_len));
+ opt = OptionPtr(new Option(Option::V4, opt_type,
+ buf.begin()+offset,
+ buf.begin()+offset+opt_len));
}
options.insert(pair<int, boost::shared_ptr<Option> >(opt_type, opt));
offset += opt_len;
}
+ return (offset);
}
-unsigned int
-LibDHCP::packOptions6(boost::shared_array<uint8_t> data,
- unsigned int data_len,
- unsigned int offset,
- const isc::dhcp::Option::OptionCollection& options) {
+void LibDHCP::packOptions6(isc::util::OutputBuffer &buf,
+ const isc::dhcp::Option::OptionCollection& options) {
try {
for (Option::OptionCollection::const_iterator it = options.begin();
- it != options.end();
- ++it) {
- unsigned short opt_len = (*it).second->len();
- if (offset + opt_len > data_len) {
- isc_throw(OutOfRange, "Failed to build option " <<
- (*it).first << ": out of buffer");
- }
- offset = it->second->pack(data, data_len, offset);
+ it != options.end(); ++it) {
+ it->second->pack(buf);
}
}
catch (const Exception&) {
cout << "Packet build failed (Option build failed)." << endl;
throw;
}
- return (offset);
}
void
@@ -156,11 +141,9 @@ LibDHCP::packOptions(isc::util::OutputBuffer& buf,
}
}
-
-bool
-LibDHCP::OptionFactoryRegister(Option::Universe u,
- unsigned short opt_type,
- Option::Factory * factory) {
+void LibDHCP::OptionFactoryRegister(Option::Universe u,
+ uint16_t opt_type,
+ Option::Factory * factory) {
switch (u) {
case Option::V6: {
if (v6factories_.find(opt_type)!=v6factories_.end()) {
@@ -168,13 +151,23 @@ LibDHCP::OptionFactoryRegister(Option::Universe u,
<< "for option type " << opt_type);
}
v6factories_[opt_type]=factory;
- return true;
+ return;
}
case Option::V4:
- default:{
- isc_throw(BadValue, "This universe type is not supported yet.");
- return false; // never happens
+ {
+ if (opt_type > 254) {
+ isc_throw(BadValue, "Too big option type for DHCPv4, only 0-254 allowed.");
+ }
+ if (v4factories_.find(opt_type)!=v4factories_.end()) {
+ isc_throw(BadValue, "There is already DHCPv4 factory registered "
+ << "for option type " << opt_type);
+ }
+ v4factories_[opt_type]=factory;
+ return;
}
+ default:
+ isc_throw(BadValue, "Invalid universe type specified.");
}
+ return;
}
diff --git a/src/lib/dhcp/libdhcp++.h b/src/lib/dhcp/libdhcp++.h
index 468e6bb..d8426b8 100644
--- a/src/lib/dhcp/libdhcp++.h
+++ b/src/lib/dhcp/libdhcp++.h
@@ -29,18 +29,10 @@ public:
///
/// Builds raw (on-wire) data for provided collection of options.
///
- /// @param buf shared pointer to buffer. Data will be stored there.
- /// @param buf_len buffer length. Used for buffer overflow protection.
- /// @param offset Offset from beginning of the buffer, where store options
+ /// @param buf output buffer (assembled options will be stored here)
/// @param options collection of options to store to
- ///
- /// @return offset to the first unused byte in buffer (next one after last
- /// used byte)
- ///
- static unsigned int
- packOptions6(boost::shared_array<uint8_t> buf, unsigned int buf_len,
- unsigned int offset,
- const isc::dhcp::Option::OptionCollection& options);
+ static void packOptions6(isc::util::OutputBuffer& buf,
+ const isc::dhcp::Option::OptionCollection& options);
/// @brief Stores options in a buffer.
@@ -52,48 +44,49 @@ public:
/// may be different reasons (option too large, option malformed,
/// too many options etc.)
///
- /// @param buf
- /// @param options
- static void
- packOptions(isc::util::OutputBuffer& buf,
- const isc::dhcp::Option::OptionCollection& options);
+ /// @param buf output buffer (assembled options will be stored here)
+ /// @param options collection of options to store to
+ static void packOptions(isc::util::OutputBuffer& buf,
+ const isc::dhcp::Option::OptionCollection& options);
- static void
- unpackOptions4(const std::vector<uint8_t>& buf,
- isc::dhcp::Option::OptionCollection& options);
- ///
- /// Parses provided buffer and creates Option objects.
+ /// @brief Parses provided buffer as DHCPv4 options and creates Option objects.
///
- /// Parses provided buf array and stores created Option objects
+ /// Parses provided buffer and stores created Option objects
/// in options container.
///
/// @param buf Buffer to be parsed.
- /// @param offset Specifies offset for the first option.
/// @param options Reference to option container. Options will be
/// put here.
+ static uint32_t unpackOptions4(const OptionBuffer& buf,
+ isc::dhcp::Option::OptionCollection& options);
+
+ /// @brief Parses provided buffer as DHCPv6 options and creates Option objects.
///
- /// @return offset to first byte after last parsed option
+ /// Parses provided buffer and stores created Option objects
+ /// in options container.
///
- static unsigned int
- unpackOptions6(const boost::shared_array<uint8_t> buf, unsigned int buf_len,
- unsigned int offset, unsigned int parse_len,
- isc::dhcp::Option::OptionCollection& options_);
+ /// @param buf Buffer to be parsed.
+ /// @param options Reference to option container. Options will be
+ /// put here.
+ static uint32_t unpackOptions6(const OptionBuffer& buf,
+ isc::dhcp::Option::OptionCollection& options);
- ///
/// Registers factory method that produces options of specific option types.
///
+ /// @exception BadValue if provided type is already registered, has too large
+ /// value or invalid universe is specified
+ ///
/// @param u universe of the option (V4 or V6)
/// @param opt_type option-type
/// @param factory function pointer
- ///
- /// @return true, if registration was successful, false otherwise
- ///
- static bool
- OptionFactoryRegister(Option::Universe u,
- unsigned short type,
- Option::Factory * factory);
+ static void OptionFactoryRegister(Option::Universe u,
+ uint16_t type,
+ Option::Factory * factory);
protected:
- // pointers to factories that produce DHCPv6 options
+ /// pointers to factories that produce DHCPv6 options
+ static std::map<unsigned short, Option::Factory*> v4factories_;
+
+ /// pointers to factories that produce DHCPv6 options
static std::map<unsigned short, Option::Factory*> v6factories_;
};
diff --git a/src/lib/dhcp/option.cc b/src/lib/dhcp/option.cc
index 23de315..aac5110 100644
--- a/src/lib/dhcp/option.cc
+++ b/src/lib/dhcp/option.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -17,7 +17,6 @@
#include <arpa/inet.h>
#include <sstream>
#include <iomanip>
-#include <boost/shared_array.hpp>
#include "exceptions/exceptions.h"
#include "util/io_utilities.h"
@@ -37,26 +36,14 @@ Option::Option(Universe u, unsigned short type)
}
}
-Option::Option(Universe u, unsigned short type,
- const boost::shared_array<uint8_t>& buf,
- unsigned int offset, unsigned int len)
- :universe_(u), type_(type),
- offset_(offset)
-{
- uint8_t* ptr = &buf[offset];
- data_ = std::vector<uint8_t>(ptr, ptr + len);
-
- check();
-}
-
-Option::Option(Universe u, unsigned short type, std::vector<uint8_t>& data)
+Option::Option(Universe u, unsigned short type, const OptionBuffer& data)
:universe_(u), type_(type), data_(data) {
check();
}
-Option::Option(Universe u, uint16_t type, vector<uint8_t>::const_iterator first,
- vector<uint8_t>::const_iterator last)
- :universe_(u), type_(type), data_(std::vector<uint8_t>(first,last)) {
+Option::Option(Universe u, uint16_t type, OptionBufferConstIter first,
+ OptionBufferConstIter last)
+ :universe_(u), type_(type), data_(OptionBuffer(first,last)) {
check();
}
@@ -84,15 +71,16 @@ Option::check() {
// both types and data size.
}
-unsigned int
-Option::pack(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset) {
- if (universe_ != V6) {
+void Option::pack(isc::util::OutputBuffer& buf) {
+ switch (universe_) {
+ case V6:
+ return pack6(buf);
+ case V4:
+ return pack4(buf);
+ default:
isc_throw(BadValue, "Failed to pack " << type_ << " option. Do not "
<< "use this method for options other than DHCPv6.");
}
- return pack6(buf, buf_len, offset);
}
void
@@ -127,84 +115,25 @@ Option::pack4(isc::util::OutputBuffer& buf) {
}
}
-unsigned int
-Option::pack6(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset) {
- if (offset+len() > buf_len) {
- isc_throw(OutOfRange, "Failed to pack v6 option=" <<
- type_ << ",len=" << len() << ": too small buffer.");
- }
-
- uint8_t* ptr = &buf[offset];
-
- ptr = writeUint16(type_, ptr);
-
- ptr = writeUint16(len() - getHeaderLen(), ptr);
-
- if (! data_.empty())
- memcpy(ptr, &data_[0], data_.size());
-
- // end of fixed part of this option
- offset += OPTION6_HDR_LEN + data_.size();
-
- return LibDHCP::packOptions6(buf, buf_len, offset, options_);
-}
+void Option::pack6(isc::util::OutputBuffer& buf) {
+ buf.writeUint16(type_);
+ buf.writeUint16(len() - getHeaderLen());
-unsigned int
-Option::unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len) {
- switch (universe_) {
- case V4:
- return unpack4(buf, buf_len, offset, parse_len);
- case V6:
- return unpack6(buf, buf_len, offset, parse_len);
- default:
- isc_throw(BadValue, "Unknown universe defined for Option " << type_);
+ if (! data_.empty()) {
+ buf.writeData(&data_[0], data_.size());
}
- return 0; // should not happen
-}
-
-unsigned int
-Option::unpack4(const boost::shared_array<uint8_t>&,
- unsigned int ,
- unsigned int ,
- unsigned int ) {
- isc_throw(Unexpected, "IPv4 support not implemented yet.");
- return 0;
+ return LibDHCP::packOptions6(buf, options_);
}
-unsigned int
-Option::unpack6(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len) {
-
- if (buf_len < offset+parse_len) {
- isc_throw(OutOfRange, "Failed to unpack DHCPv6 option len="
- << parse_len << " offset=" << offset
- << " from buffer (length=" << buf_len
- << "): too small buffer.");
- }
-
- uint8_t* ptr = &buf[offset];
- data_ = std::vector<uint8_t>(ptr, ptr + parse_len);
-
- offset_ = offset;
-
- return (offset+parse_len);
-
- //return LibDHCP::unpackOptions6(buf, buf_len, offset, parse_len,
- // options_);
+void Option::unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end) {
+ data_ = OptionBuffer(begin, end);
}
-/// Returns length of the complete option (data length + DHCPv4/DHCPv6
-/// option header)
-uint16_t
-Option::len() {
+uint16_t Option::len() {
+ // Returns length of the complete option (data length + DHCPv4/DHCPv6
+ // option header)
// length of the whole option is header and data stored in this option...
int length = getHeaderLen() + data_.size();
@@ -232,18 +161,16 @@ Option::valid() {
return (true);
}
-boost::shared_ptr<isc::dhcp::Option>
-Option::getOption(unsigned short opt_type) {
+OptionPtr Option::getOption(unsigned short opt_type) {
isc::dhcp::Option::OptionCollection::const_iterator x =
options_.find(opt_type);
if ( x != options_.end() ) {
return (*x).second;
}
- return boost::shared_ptr<isc::dhcp::Option>(); // NULL
+ return OptionPtr(); // NULL
}
-bool
-Option::delOption(unsigned short opt_type) {
+bool Option::delOption(unsigned short opt_type) {
isc::dhcp::Option::OptionCollection::iterator x = options_.find(opt_type);
if ( x != options_.end() ) {
options_.erase(x);
@@ -289,8 +216,7 @@ Option::getHeaderLen() {
return 0; // should not happen
}
-void
-Option::addOption(boost::shared_ptr<Option> opt) {
+void Option::addOption(OptionPtr opt) {
if (universe_ == V4) {
// check for uniqueness (DHCPv4 options must be unique)
if (getOption(opt->getType())) {
@@ -298,7 +224,7 @@ Option::addOption(boost::shared_ptr<Option> opt) {
<< " already present in this message.");
}
}
- options_.insert(pair<int, boost::shared_ptr<Option> >(opt->getType(), opt));
+ options_.insert(pair<int, OptionPtr >(opt->getType(), opt));
}
uint8_t Option::getUint8() {
diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h
index d80fc05..f0dec3b 100644
--- a/src/lib/dhcp/option.h
+++ b/src/lib/dhcp/option.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -19,12 +19,28 @@
#include <map>
#include <vector>
#include <boost/shared_ptr.hpp>
-#include <boost/shared_array.hpp>
#include <util/buffer.h>
namespace isc {
namespace dhcp {
+/// buffer types used in DHCP code
+typedef std::vector<uint8_t> OptionBuffer;
+
+/// iterator for walking over OptionBuffer
+typedef OptionBuffer::iterator OptionBufferIter;
+
+/// const_iterator for walking over OptionBuffer
+typedef OptionBuffer::const_iterator OptionBufferConstIter;
+
+/// pointer to a DHCP buffer
+typedef boost::shared_ptr< OptionBuffer > OptionBufferPtr;
+
+/// shared pointer to Option object
+class Option;
+typedef boost::shared_ptr<Option> OptionPtr;
+
+
class Option {
public:
/// length of the usual DHCPv4 option header (there are exceptions)
@@ -37,7 +53,7 @@ public:
enum Universe { V4, V6 };
/// a collection of DHCPv6 options
- typedef std::multimap<unsigned int, boost::shared_ptr<Option> >
+ typedef std::multimap<unsigned int, OptionPtr >
OptionCollection;
/// @brief a factory function prototype
@@ -45,38 +61,17 @@ public:
/// @param u option universe (DHCPv4 or DHCPv6)
/// @param type option type
/// @param buf pointer to a buffer
- /// @param offset offset to first data byte in that buffer
- /// @param len data length of this option
///
/// @return a pointer to a created option object
- typedef boost::shared_ptr<Option> Factory(Option::Universe u,
- unsigned short type,
- boost::shared_array<uint8_t>& buf,
- unsigned int offset,
- unsigned int len);
+ typedef OptionPtr Factory(Option::Universe u,
+ uint16_t type,
+ const OptionBuffer& buf);
/// @brief ctor, used for options constructed, usually during transmission
///
/// @param u option universe (DHCPv4 or DHCPv6)
/// @param type option type
- Option(Universe u, unsigned short type);
-
- /// @brief ctor, used for received options
- ///
- /// boost::shared_array allows sharing a buffer, but it requires that
- /// different instances share pointer to the whole array, not point
- /// to different elements in shared array. Therefore we need to share
- /// pointer to the whole array and remember offset where data for
- /// this option begins
- ///
- /// @param u specifies universe (V4 or V6)
- /// @param type option type
- /// @param buf pointer to a buffer
- /// @param offset offset in a buffer pointing to first byte of data
- /// @param len length of the option data
- Option(Universe u, unsigned short type,
- const boost::shared_array<uint8_t>& buf, unsigned int offset,
- unsigned int len);
+ Option(Universe u, uint16_t type);
/// @brief Constructor, used for received options.
///
@@ -88,7 +83,7 @@ public:
/// @param u specifies universe (V4 or V6)
/// @param type option type (0-255 for V4 and 0-65535 for V6)
/// @param data content of the option
- Option(Universe u, unsigned short type, std::vector<uint8_t>& data);
+ Option(Universe u, uint16_t type, const OptionBuffer& data);
/// @brief Constructor, used for received options.
///
@@ -110,15 +105,13 @@ public:
/// @param first iterator to the first element that should be copied
/// @param last iterator to the next element after the last one
/// to be copied.
- Option(Universe u, uint16_t type,
- std::vector<uint8_t>::const_iterator first,
- std::vector<uint8_t>::const_iterator last);
+ Option(Universe u, uint16_t type, OptionBufferConstIter first,
+ OptionBufferConstIter last);
/// @brief returns option universe (V4 or V6)
///
/// @return universe type
- Universe
- getUniverse() { return universe_; };
+ Universe getUniverse() { return universe_; };
/// @brief Writes option in wire-format to a buffer.
///
@@ -129,14 +122,10 @@ public:
/// TODO: Migrate DHCPv6 code to pack(OutputBuffer& buf) version
///
/// @param buf pointer to a buffer
- /// @param buf_len length of the buffer
- /// @param offset offset to place, where option shout be stored
///
/// @return offset to first unused byte after stored option
///
- virtual unsigned int
- pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
- unsigned int offset);
+ virtual void pack(isc::util::OutputBuffer& buf);
/// @brief Writes option in a wire-format to a buffer.
///
@@ -146,26 +135,17 @@ public:
/// unify pack4() and pack6() and rename them to just pack().
///
/// @param buf output buffer (option will be stored there)
- virtual void
- pack4(isc::util::OutputBuffer& buf);
-
+ virtual void pack4(isc::util::OutputBuffer& buf);
/// @brief Parses buffer.
///
/// Parses received buffer, returns offset to the first unused byte after
/// parsed option.
///
- /// @param buf pointer to buffer
- /// @param buf_len length of buf
- /// @param offset offset, where start parsing option
- /// @param parse_len how many bytes should be parsed
- ///
- /// @return offset after last parsed octet
- virtual unsigned int
- unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ virtual void unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end);
/// Returns string representation of the option.
///
@@ -203,7 +183,7 @@ public:
///
/// @return pointer to actual data (or reference to an empty vector
/// if there is no data)
- virtual const std::vector<uint8_t>& getData() { return (data_); }
+ virtual const OptionBuffer& getData() { return (data_); }
/// Adds a sub-option.
///
@@ -217,24 +197,21 @@ public:
/// many places. Requiring casting is not feasible.
///
/// @param opt shared pointer to a suboption that is going to be added.
- void
- addOption(boost::shared_ptr<Option> opt);
+ void addOption(OptionPtr opt);
/// Returns shared_ptr to suboption of specific type
///
/// @param type type of requested suboption
///
/// @return shared_ptr to requested suoption
- boost::shared_ptr<isc::dhcp::Option>
- getOption(unsigned short type);
+ OptionPtr getOption(uint16_t type);
/// Attempts to delete first suboption of requested type
///
/// @param type Type of option to be deleted.
///
/// @return true if option was deleted, false if no such option existed
- bool
- delOption(unsigned short type);
+ bool delOption(uint16_t type);
/// @brief Returns content of first byte.
///
@@ -286,40 +263,7 @@ protected:
/// defined suboptions. Version for building DHCPv4 options.
///
/// @param buf output buffer (built options will be stored here)
- /// @param buf_len buffer length (used for buffer overflow checks)
- /// @param offset offset from start of the buf buffer
- ///
- /// @return offset to the next byte after last used byte
- virtual unsigned int
- pack6(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset);
-
- /// Parses provided buffer and creates DHCPv4 options.
- ///
- /// @param buf buffer that contains raw buffer to parse (on-wire format)
- /// @param buf_len buffer length (used for buffer overflow checks)
- /// @param offset offset from start of the buf buffer
- ///
- /// @return offset to the next byte after last parsed byte
- virtual unsigned int
- unpack4(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len);
-
- /// Parses provided buffer and creates DHCPv6 options.
- ///
- /// @param buf buffer that contains raw buffer to parse (on-wire format)
- /// @param buf_len buffer length (used for buffer overflow checks)
- /// @param offset offset from start of the buf buffer
- ///
- /// @return offset to the next byte after last parsed byte
- virtual unsigned int
- unpack6(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len);
+ virtual void pack6(isc::util::OutputBuffer& buf);
/// @brief A private method used for option correctness.
///
@@ -332,17 +276,10 @@ protected:
Universe universe_;
/// option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
- unsigned short type_;
+ uint16_t type_;
/// contains content of this data
- std::vector<uint8_t> data_;
-
- /// TODO: Remove this field. vector<uint8_t> should be used
- /// instead.
- /// data is a shared_pointer that points out to the
- /// whole packet. offset_ specifies where data for
- /// this option begins.
- unsigned int offset_;
+ OptionBuffer data_;
/// collection for storing suboptions
OptionCollection options_;
diff --git a/src/lib/dhcp/option4_addrlst.cc b/src/lib/dhcp/option4_addrlst.cc
index 88eb915..7157e1d 100644
--- a/src/lib/dhcp/option4_addrlst.cc
+++ b/src/lib/dhcp/option4_addrlst.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -38,9 +38,8 @@ Option4AddrLst::Option4AddrLst(uint8_t type, const AddressContainer& addrs)
}
-Option4AddrLst::Option4AddrLst(uint8_t type,
- vector<uint8_t>::const_iterator first,
- vector<uint8_t>::const_iterator last)
+Option4AddrLst::Option4AddrLst(uint8_t type, OptionBufferConstIter first,
+ OptionBufferConstIter last)
:Option(V4, type) {
if ( (distance(first, last) % V4ADDRESS_LEN) ) {
isc_throw(OutOfRange, "DHCPv4 Option4AddrLst " << type_
diff --git a/src/lib/dhcp/option4_addrlst.h b/src/lib/dhcp/option4_addrlst.h
index c795805..3bedc6d 100644
--- a/src/lib/dhcp/option4_addrlst.h
+++ b/src/lib/dhcp/option4_addrlst.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -77,8 +77,8 @@ public:
/// @param first iterator to the first element that should be copied
/// @param last iterator to the next element after the last one
/// to be copied.
- Option4AddrLst(uint8_t type, std::vector<uint8_t>::const_iterator first,
- std::vector<uint8_t>::const_iterator last);
+ Option4AddrLst(uint8_t type, OptionBufferConstIter first,
+ OptionBufferConstIter last);
/// @brief Writes option in a wire-format to a buffer.
///
@@ -88,16 +88,14 @@ public:
/// unify pack4() and pack6() and rename them to just pack().
///
/// @param buf output buffer (option will be stored there)
- virtual void
- pack4(isc::util::OutputBuffer& buf);
+ virtual void pack4(isc::util::OutputBuffer& buf);
/// Returns string representation of the option.
///
/// @param indent number of spaces before printing text
///
/// @return string with text representation.
- virtual std::string
- toText(int indent = 0);
+ virtual std::string toText(int indent = 0);
/// Returns length of the complete option (data length + DHCPv4/DHCPv6
/// option header)
@@ -113,8 +111,7 @@ public:
/// a couple (1-3) addresses, the overhead is not that big.
///
/// @return address container with addresses
- AddressContainer
- getAddresses() { return addrs_; };
+ AddressContainer getAddresses() { return addrs_; };
/// @brief Sets addresses list.
///
diff --git a/src/lib/dhcp/option6_addrlst.cc b/src/lib/dhcp/option6_addrlst.cc
index fb082fa..fdd0df9 100644
--- a/src/lib/dhcp/option6_addrlst.cc
+++ b/src/lib/dhcp/option6_addrlst.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -40,12 +40,10 @@ Option6AddrLst::Option6AddrLst(unsigned short type,
}
Option6AddrLst::Option6AddrLst(unsigned short type,
- boost::shared_array<uint8_t> buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int option_len)
+ OptionBufferConstIter begin,
+ OptionBufferConstIter end)
:Option(V6, type) {
- unpack(buf, buf_len, offset, option_len);
+ unpack(begin, end);
}
void
@@ -63,58 +61,32 @@ Option6AddrLst::setAddresses(const AddressContainer& addrs) {
addrs_ = addrs;
}
-unsigned int
-Option6AddrLst::pack(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset) {
- if (len() > buf_len) {
- isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
- << ", buffer=" << buf_len << ": too small buffer.");
- }
+void Option6AddrLst::pack(isc::util::OutputBuffer& buf) {
- writeUint16(type_, &buf[offset]);
- offset += sizeof(uint16_t);
+ buf.writeUint16(type_);
// len() returns complete option length.
// len field contains length without 4-byte option header
- writeUint16(len() - OPTION6_HDR_LEN, &buf[offset]);
- offset += sizeof(uint16_t);
+ buf.writeUint16(len() - getHeaderLen());
// this wrapping is *ugly*. I wish there was a a
for (AddressContainer::const_iterator addr=addrs_.begin();
- addr!=addrs_.end();
- ++addr) {
- memcpy(&buf[offset],
- addr->getAddress().to_v6().to_bytes().data(),
- V6ADDRESS_LEN);
- offset += V6ADDRESS_LEN;
+ addr!=addrs_.end(); ++addr) {
+ buf.writeData(addr->getAddress().to_v6().to_bytes().data(), V6ADDRESS_LEN);
}
-
- return offset;
}
-unsigned int
-Option6AddrLst::unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int option_len) {
- if (offset+option_len > buf_len) {
+void Option6AddrLst::unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end) {
+ if (distance(begin, end) % 16) {
isc_throw(OutOfRange, "Option " << type_
- << " truncated.");
- }
-
- if (option_len%16) {
- isc_throw(OutOfRange, "Option " << type_
- << " malformed: len=" << option_len
+ << " malformed: len=" << distance(begin, end)
<< " is not divisible by 16.");
}
- while (option_len > 0) {
- addrs_.push_back(IOAddress::from_bytes(AF_INET6, &buf[offset]));
- offset += 16;
- option_len -= 16;
+ while (begin != end) {
+ addrs_.push_back(IOAddress::from_bytes(AF_INET6, &(*begin)));
+ begin += V6ADDRESS_LEN;
}
-
- return offset;
}
std::string Option6AddrLst::toText(int indent /* =0 */) {
diff --git a/src/lib/dhcp/option6_addrlst.h b/src/lib/dhcp/option6_addrlst.h
index a73dc55..34daa24 100644
--- a/src/lib/dhcp/option6_addrlst.h
+++ b/src/lib/dhcp/option6_addrlst.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -36,70 +36,48 @@ public:
///
/// @param type option type
/// @param addrs vector of addresses to be stored
- ///
- Option6AddrLst(unsigned short type,
- const AddressContainer& addrs);
+ Option6AddrLst(uint16_t type, const AddressContainer& addrs);
/// @brief Simplified constructor for a single address
///
/// @param type option type
/// @param addr a single address to be stored
- ///
- Option6AddrLst(unsigned short type,
- const isc::asiolink::IOAddress& addr);
+ Option6AddrLst(uint16_t type, const isc::asiolink::IOAddress& addr);
/// @brief Constructor used for parsing received option
///
/// @param type option type
- /// @param buf pointer to packet buffer
- /// @param buf_len length of packet buffer
- /// @param offset offset to beginning of option data
- /// @param len length of option data
- ///
- Option6AddrLst(unsigned short type, boost::shared_array<uint8_t> buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ Option6AddrLst(uint16_t type, OptionBufferConstIter begin,
+ OptionBufferConstIter end);
/// @brief Assembles on-wire form of this option
///
/// @param buf pointer to packet buffer
- /// @param buf_len length of packet buffer
- /// @param offset offset to place, where option is to be stored
- ///
- /// @return offset to the next unused char (just after stored option)
- ///
- unsigned int
- pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
- unsigned int offset);
+ void pack(isc::util::OutputBuffer& buf);
/// @brief Parses received data
///
/// @param buf pointer to packet buffer
- /// @param buf_len length of packet buffer
/// @param offset offset to option data
/// @param parse_len specified option data length
///
/// @return offset to the next unparsed char (just after parsed option)
///
- virtual unsigned int
- unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len);
+ virtual void unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end);
virtual std::string toText(int indent = 0);
/// @brief Sets a single address.
///
/// @param addr a single address to be added
- ///
void setAddress(const isc::asiolink::IOAddress& addr);
/// @brief Sets list of addresses.
///
/// @param addrs a vector of addresses to be added
- ///
void setAddresses(const AddressContainer& addrs);
/// @brief Returns vector with addresses.
@@ -110,8 +88,7 @@ public:
/// a couple (1-3) addresses, the overhead is not that big.
///
/// @return address container with addresses
- AddressContainer
- getAddresses() { return addrs_; };
+ AddressContainer getAddresses() { return addrs_; };
// returns data length (data length + DHCPv4/DHCPv6 option header)
virtual uint16_t len();
diff --git a/src/lib/dhcp/option6_ia.cc b/src/lib/dhcp/option6_ia.cc
index cd55553..fccbd95 100644
--- a/src/lib/dhcp/option6_ia.cc
+++ b/src/lib/dhcp/option6_ia.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -15,12 +15,12 @@
#include <stdint.h>
#include <arpa/inet.h>
#include <sstream>
-#include "exceptions/exceptions.h"
-#include "dhcp/libdhcp++.h"
-#include "dhcp/option6_ia.h"
-#include "dhcp/dhcp6.h"
-#include "util/io_utilities.h"
+#include <exceptions/exceptions.h>
+#include <dhcp/libdhcp++.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/dhcp6.h>
+#include <util/io_utilities.h>
using namespace std;
using namespace isc;
@@ -32,65 +32,36 @@ Option6IA::Option6IA(unsigned short type, unsigned int iaid)
}
Option6IA::Option6IA(unsigned short type,
- const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int option_len)
+ OptionBufferConstIter begin,
+ OptionBufferConstIter end)
:Option(Option::V6, type) {
- unpack(buf, buf_len, offset, option_len);
+ unpack(begin, end);
}
-unsigned int
-Option6IA::pack(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset) {
- if (offset + len() > buf_len) {
- isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
- << ", buffer=" << buf_len << ": too small buffer.");
- }
-
- if (len() < 16 ) {
- isc_throw(OutOfRange, "Attempt to build malformed IA option: len="
- << len() << " is too small (at least 16 is required).");
- }
-
- uint8_t* ptr = &buf[offset];
-
- ptr = writeUint16(type_, ptr);
- ptr = writeUint16(len() - OPTION6_HDR_LEN, ptr);
- offset += OPTION6_HDR_LEN;
+void Option6IA::pack(isc::util::OutputBuffer& buf) {
+ buf.writeUint16(type_);
+ buf.writeUint16(len() - OPTION6_HDR_LEN);
+ buf.writeUint32(iaid_);
+ buf.writeUint32(t1_);
+ buf.writeUint32(t2_);
- ptr = writeUint32(iaid_, ptr);
- ptr = writeUint32(t1_, ptr);
- ptr = writeUint32(t2_, ptr);
- offset += OPTION6_IA_LEN;
-
- offset = LibDHCP::packOptions6(buf, buf_len, offset, options_);
- return offset;
+ LibDHCP::packOptions6(buf, options_);
}
-unsigned int
-Option6IA::unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len) {
- if ( parse_len < OPTION6_IA_LEN || offset + OPTION6_IA_LEN > buf_len) {
+void Option6IA::unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end) {
+ if (distance(begin, end) < 12) {
isc_throw(OutOfRange, "Option " << type_ << " truncated");
}
+ iaid_ = readUint32( &(*begin) );
+ begin += sizeof(uint32_t);
+ t1_ = readUint32( &(*begin) );
+ begin += sizeof(uint32_t);
- iaid_ = readUint32(&buf[offset]);
- offset += sizeof(uint32_t);
-
- t1_ = readUint32(&buf[offset]);
- offset += sizeof(uint32_t);
-
- t2_ = readUint32(&buf[offset]);
- offset += sizeof(uint32_t);
-
- offset = LibDHCP::unpackOptions6(buf, buf_len, offset,
- parse_len - OPTION6_IA_LEN, options_);
+ t2_ = readUint32( &(*begin) );
+ begin += sizeof(uint32_t);
- return (offset);
+ LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
}
std::string Option6IA::toText(int indent /* = 0*/) {
diff --git a/src/lib/dhcp/option6_ia.h b/src/lib/dhcp/option6_ia.h
index cab8068..c2089d4 100644
--- a/src/lib/dhcp/option6_ia.h
+++ b/src/lib/dhcp/option6_ia.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -27,54 +27,34 @@ public:
/// Length of IA_NA and IA_PD content
const static size_t OPTION6_IA_LEN = 12;
- /// @brief ctor, used for options constructed, usually during transmission
+ /// @brief Ctor, used for constructed options, usually during transmission.
///
/// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
/// @param iaid identity association identifier (id of IA)
- Option6IA(uint16_t type, unsigned int iaid);
+ Option6IA(uint16_t type, uint32_t iaid);
- /// @brief ctor, used for received options
- ///
- /// boost::shared_array allows sharing a buffer, but it requires that
- /// different instances share pointer to the whole array, not point
- /// to different elements in shared array. Therefore we need to share
- /// pointer to the whole array and remember offset where data for
- /// this option begins
+ /// @brief Ctor, used for received options.
///
/// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
- /// @param buf buffer to be parsed
- /// @param buf_len buffer length
- /// @param offset offset in buffer
- /// @param len number of bytes to parse
- Option6IA(uint16_t type, const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len, unsigned int offset, unsigned int len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ Option6IA(uint16_t type, OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end);
/// Writes option in wire-format to buf, returns pointer to first unused
/// byte after stored option.
///
/// @param buf buffer (option will be stored here)
- /// @param buf_len (buffer length)
- /// @param offset offset place where option should be stored
- ///
- /// @return offset to the first unused byte after stored option
- unsigned int
- pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
- unsigned int offset);
+ void pack(isc::util::OutputBuffer& buf);
/// @brief Parses received buffer
///
/// Parses received buffer and returns offset to the first unused byte after
/// parsed option.
///
- /// @param buf pointer to buffer
- /// @param buf_len length of buf
- /// @param offset offset, where start parsing option
- /// @param parse_len how many bytes should be parsed
- ///
- /// @return offset after last parsed octet
- virtual unsigned int
- unpack(const boost::shared_array<uint8_t>& buf, unsigned int buf_len,
- unsigned int offset, unsigned int parse_len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end);
/// Provides human readable text representation
///
@@ -87,48 +67,46 @@ public:
/// Sets T1 timer.
///
/// @param t1 t1 value to be set
- void setT1(unsigned int t1) { t1_=t1; }
-
+ void setT1(uint32_t t1) { t1_=t1; }
/// Sets T2 timer.
///
/// @param t2 t2 value to be set
- void setT2(unsigned int t2) { t2_=t2; }
+ void setT2(uint32_t t2) { t2_=t2; }
/// Returns IA identifier.
///
/// @return IAID value.
///
- unsigned int getIAID() const { return iaid_; }
+ uint32_t getIAID() const { return iaid_; }
/// Returns T1 timer.
///
/// @return T1 value.
- unsigned int getT1() const { return t1_; }
+ uint32_t getT1() const { return t1_; }
/// Returns T2 timer.
///
/// @return T2 value.
- unsigned int getT2() const { return t2_; }
+ uint32_t getT2() const { return t2_; }
/// @brief returns complete length of option
///
/// Returns length of this option, including option header and suboptions
///
/// @return length of this option
- virtual uint16_t
- len();
+ virtual uint16_t len();
protected:
/// keeps IA identifier
- unsigned int iaid_;
+ uint32_t iaid_;
/// keeps T1 timer value
- unsigned int t1_;
+ uint32_t t1_;
/// keeps T2 timer value
- unsigned int t2_;
+ uint32_t t2_;
};
} // isc::dhcp namespace
diff --git a/src/lib/dhcp/option6_iaaddr.cc b/src/lib/dhcp/option6_iaaddr.cc
index 70c2948..3e25c62 100644
--- a/src/lib/dhcp/option6_iaaddr.cc
+++ b/src/lib/dhcp/option6_iaaddr.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -36,67 +36,47 @@ Option6IAAddr::Option6IAAddr(unsigned short type,
valid_(valid) {
}
-Option6IAAddr::Option6IAAddr(unsigned short type,
- boost::shared_array<uint8_t> buf,
- unsigned int buf_len, unsigned int offset,
- unsigned int option_len)
+Option6IAAddr::Option6IAAddr(uint32_t type, OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end)
:Option(V6, type), addr_("::") {
- unpack(buf, buf_len, offset, option_len);
+ unpack(begin, end);
}
-unsigned int
-Option6IAAddr::pack(boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset) {
- if (len() > buf_len) {
- isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
- << ", buffer=" << buf_len << ": too small buffer.");
- }
-
- uint8_t* ptr = &buf[offset];
+void Option6IAAddr::pack(isc::util::OutputBuffer& buf) {
- ptr = writeUint16(type_, ptr);
+ buf.writeUint16(type_);
// len() returns complete option length. len field contains
// length without 4-byte option header
- ptr = writeUint16(len() - OPTION6_HDR_LEN, ptr);
- offset += OPTION6_HDR_LEN;
+ buf.writeUint16(len() - getHeaderLen());
- memcpy(ptr, addr_.getAddress().to_v6().to_bytes().data(), 16);
- ptr += V6ADDRESS_LEN;
- ptr = writeUint32(preferred_, ptr);
+ buf.writeData(addr_.getAddress().to_v6().to_bytes().data(),
+ isc::asiolink::V6ADDRESS_LEN);
- ptr = writeUint32(valid_, ptr);
- offset += OPTION6_IAADDR_LEN;
+ buf.writeUint32(preferred_);
+ buf.writeUint32(valid_);
- // parse suboption (there shouldn't be any)
- offset = LibDHCP::packOptions6(buf, buf_len, offset, options_);
- return offset;
+ // parse suboption (there shouldn't be any for IAADDR)
+ LibDHCP::packOptions6(buf, options_);
}
-unsigned int
-Option6IAAddr::unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len) {
- if ( parse_len < OPTION6_IAADDR_LEN || offset + OPTION6_IAADDR_LEN > buf_len) {
+void Option6IAAddr::unpack(OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end) {
+ if ( distance(begin, end) < OPTION6_IAADDR_LEN) {
isc_throw(OutOfRange, "Option " << type_ << " truncated");
}
// 16 bytes: IPv6 address
- addr_ = IOAddress::from_bytes(AF_INET6, &buf[offset]);
- offset += V6ADDRESS_LEN;
-
- preferred_ = readUint32(&buf[offset]);
- offset += sizeof(uint32_t);
+ addr_ = IOAddress::from_bytes(AF_INET6, &(*begin));
+ begin += V6ADDRESS_LEN;
- valid_ = readUint32(&buf[offset]);
- offset += sizeof(uint32_t);
- offset = LibDHCP::unpackOptions6(buf, buf_len, offset,
- parse_len - 24, options_);
+ preferred_ = readUint32( &(*begin) );
+ begin += sizeof(uint32_t);
- return offset;
+ valid_ = readUint32( &(*begin) );
+ begin += sizeof(uint32_t);
+ LibDHCP::unpackOptions6(OptionBuffer(begin, end), options_);
}
std::string Option6IAAddr::toText(int indent /* =0 */) {
diff --git a/src/lib/dhcp/option6_iaaddr.h b/src/lib/dhcp/option6_iaaddr.h
index 40e5967..6ca4cc0 100644
--- a/src/lib/dhcp/option6_iaaddr.h
+++ b/src/lib/dhcp/option6_iaaddr.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -27,28 +27,22 @@ public:
/// length of the fixed part of the IAADDR option
static const size_t OPTION6_IAADDR_LEN = 24;
- /// @brief ctor, used for options constructed (during transmission)
+ /// @brief Ctor, used for options constructed (during transmission).
///
/// @param type option type
/// @param addr reference to an address
/// @param preferred address preferred lifetime (in seconds)
/// @param valid address valid lifetime (in seconds)
- Option6IAAddr(unsigned short type, const isc::asiolink::IOAddress& addr,
- unsigned int preferred, unsigned int valid);
+ Option6IAAddr(uint16_t type, const isc::asiolink::IOAddress& addr,
+ uint32_t preferred, uint32_t valid);
- /// ctor, used for received options
- /// boost::shared_array allows sharing a buffer, but it requires that
- /// different instances share pointer to the whole array, not point
- /// to different elements in shared array. Therefore we need to share
- /// pointer to the whole array and remember offset where data for
- /// this option begins
+ /// @brief ctor, used for received options.
///
/// @param type option type
- /// @param buf pointer to a buffer
- /// @param offset offset to first data byte in that buffer
- /// @param len data length of this option
- Option6IAAddr(unsigned short type, boost::shared_array<uint8_t> buf,
- unsigned int buf_len, unsigned int offset, unsigned int len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ Option6IAAddr(uint32_t type, OptionBuffer::const_iterator begin,
+ OptionBuffer::const_iterator end);
/// @brief Writes option in wire-format.
///
@@ -56,13 +50,7 @@ public:
/// byte after stored option.
///
/// @param buf pointer to a buffer
- /// @param buf_len length of the buffer
- /// @param offset offset to place, where option shout be stored
- ///
- /// @return offset to first unused byte after stored option
- unsigned int
- pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
- unsigned int offset);
+ void pack(isc::util::OutputBuffer& buf);
/// @brief Parses buffer.
///
@@ -70,16 +58,10 @@ public:
/// parsed option.
///
/// @param buf pointer to buffer
- /// @param buf_len length of buf
- /// @param offset offset, where start parsing option
- /// @param parse_len how many bytes should be parsed
- ///
- /// @return offset after last parsed octet
- virtual unsigned int
- unpack(const boost::shared_array<uint8_t>& buf,
- unsigned int buf_len,
- unsigned int offset,
- unsigned int parse_len);
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ virtual void unpack(OptionBufferConstIter begin,
+ OptionBufferConstIter end);
/// Returns string representation of the option.
///
diff --git a/src/lib/dhcp/pkt4.h b/src/lib/dhcp/pkt4.h
index c520747..78fb621 100644
--- a/src/lib/dhcp/pkt4.h
+++ b/src/lib/dhcp/pkt4.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -18,7 +18,6 @@
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
-#include <boost/shared_array.hpp>
#include "asiolink/io_address.h"
#include "util/buffer.h"
#include "dhcp/option.h"
@@ -103,8 +102,7 @@ public:
/// This function is useful mainly for debugging.
///
/// @return string with text representation
- std::string
- toText();
+ std::string toText();
/// @brief Returns the size of the required buffer to build the packet.
///
@@ -112,118 +110,110 @@ public:
/// the current set of packet options.
///
/// @return number of bytes required to build this packet
- size_t
- len();
+ size_t len();
- /// Sets hops field
+ /// @brief Sets hops field.
///
/// @param hops value to be set
- void
- setHops(uint8_t hops) { hops_ = hops; };
+ void setHops(uint8_t hops) { hops_ = hops; };
- /// Returns hops field
+ /// @brief Returns hops field.
///
/// @return hops field
- uint8_t
- getHops() const { return (hops_); };
+ uint8_t getHops() const { return (hops_); };
// Note: There's no need to manipulate OP field directly,
// thus no setOp() method. See op_ comment.
- /// Returns op field
+ /// @brief Returns op field.
///
/// @return op field
- uint8_t
- getOp() const { return (op_); };
+ uint8_t getOp() const { return (op_); };
- /// Sets secs field
+ /// @brief Sets secs field.
///
/// @param secs value to be set
- void
- setSecs(uint16_t secs) { secs_ = secs; };
+ void setSecs(uint16_t secs) { secs_ = secs; };
- /// Returns secs field
+ /// @brief Returns secs field.
///
/// @return secs field
- uint16_t
- getSecs() const { return (secs_); };
+ uint16_t getSecs() const { return (secs_); };
- /// Sets flags field
+ /// @brief Sets flags field.
///
/// @param flags value to be set
- void
- setFlags(uint16_t flags) { flags_ = flags; };
+ void setFlags(uint16_t flags) { flags_ = flags; };
- /// Returns flags field
+ /// @brief Returns flags field.
///
/// @return flags field
- uint16_t
- getFlags() const { return (flags_); };
+ uint16_t getFlags() const { return (flags_); };
- /// Returns ciaddr field
+ /// @brief Returns ciaddr field.
///
/// @return ciaddr field
const isc::asiolink::IOAddress&
getCiaddr() const { return (ciaddr_); };
- /// Sets ciaddr field
+ /// @brief Sets ciaddr field.
///
/// @param ciaddr value to be set
void
setCiaddr(const isc::asiolink::IOAddress& ciaddr) { ciaddr_ = ciaddr; };
- /// Returns siaddr field
+ /// @brief Returns siaddr field.
///
/// @return siaddr field
const isc::asiolink::IOAddress&
getSiaddr() const { return (siaddr_); };
- /// Sets siaddr field
+ /// @brief Sets siaddr field.
///
/// @param siaddr value to be set
void
setSiaddr(const isc::asiolink::IOAddress& siaddr) { siaddr_ = siaddr; };
- /// Returns yiaddr field
+ /// @brief Returns yiaddr field.
///
/// @return yiaddr field
const isc::asiolink::IOAddress&
getYiaddr() const { return (yiaddr_); };
- /// Sets yiaddr field
+ /// @brief Sets yiaddr field.
///
/// @param yiaddr value to be set
void
setYiaddr(const isc::asiolink::IOAddress& yiaddr) { yiaddr_ = yiaddr; };
- /// Returns giaddr field
+ /// @brief Returns giaddr field.
///
/// @return giaddr field
const isc::asiolink::IOAddress&
getGiaddr() const { return (giaddr_); };
- /// Sets giaddr field
+ /// @brief Sets giaddr field.
///
/// @param giaddr value to be set
void
setGiaddr(const isc::asiolink::IOAddress& giaddr) { giaddr_ = giaddr; };
- /// Returns value of transaction-id field
+ /// @brief Returns value of transaction-id field.
///
/// @return transaction-id
uint32_t getTransid() const { return (transid_); };
- /// Returns message type (e.g. 1 = DHCPDISCOVER)
+ /// @brief Returns message type (e.g. 1 = DHCPDISCOVER).
///
/// @return message type
uint8_t
getType() const { return (msg_type_); }
- /// Sets message type (e.g. 1 = DHCPDISCOVER)
+ /// @brief Sets message type (e.g. 1 = DHCPDISCOVER).
///
/// @param type message type to be set
void setType(uint8_t type) { msg_type_=type; };
@@ -234,14 +224,13 @@ public:
/// null-terminated. Do not use strlen() or similar on it.
///
/// @return sname field
- const std::vector<uint8_t>
+ const OptionBuffer
getSname() const { return (std::vector<uint8_t>(sname_, &sname_[MAX_SNAME_LEN])); };
- /// Sets sname field
+ /// @brief Sets sname field.
///
/// @param sname value to be set
- void
- setSname(const uint8_t* sname, size_t snameLen = MAX_SNAME_LEN);
+ void setSname(const uint8_t* sname, size_t snameLen = MAX_SNAME_LEN);
/// @brief Returns file field
///
@@ -249,7 +238,7 @@ public:
/// null-terminated. Do not use strlen() or similar on it.
///
/// @return pointer to file field
- const std::vector<uint8_t>
+ const OptionBuffer
getFile() const { return (std::vector<uint8_t>(file_, &file_[MAX_FILE_LEN])); };
/// Sets file field
@@ -478,7 +467,7 @@ protected:
// end of real DHCPv4 fields
- /// output buffer (used during message
+ /// output buffer (used during message transmission)
isc::util::OutputBuffer bufferOut_;
// that's the data of input buffer used in RX packet. Note that
@@ -496,6 +485,8 @@ protected:
isc::dhcp::Option::OptionCollection options_;
}; // Pkt4 class
+typedef boost::shared_ptr<Pkt4> Pkt4Ptr;
+
} // isc::dhcp namespace
} // isc namespace
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index ff27d5e..780cc64 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -25,43 +25,36 @@ using namespace isc::dhcp;
namespace isc {
-Pkt6::Pkt6(unsigned int dataLen, DHCPv6Proto proto /* = UDP */)
- :data_len_(dataLen),
- local_addr_("::"),
- remote_addr_("::"),
- iface_(""),
- ifindex_(-1),
- local_port_(-1),
- remote_port_(-1),
- proto_(proto),
- msg_type_(-1),
- transid_(rand()%0xffffff)
-{
-
- data_ = boost::shared_array<uint8_t>(new uint8_t[dataLen]);
- data_len_ = dataLen;
+Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */) :
+ proto_(proto),
+ msg_type_(-1),
+ transid_(rand()%0xffffff),
+ iface_(""),
+ ifindex_(-1),
+ local_addr_("::"),
+ remote_addr_("::"),
+ local_port_(-1),
+ remote_port_(-1),
+ bufferOut_(0) {
+ data_.resize(buf_len);
+ memcpy(&data_[0], buf, buf_len);
}
-Pkt6::Pkt6(uint8_t msg_type,
- unsigned int transid,
- DHCPv6Proto proto /*= UDP*/)
- :local_addr_("::"),
- remote_addr_("::"),
- iface_(""),
- ifindex_(-1),
- local_port_(-1),
- remote_port_(-1),
- proto_(proto),
- msg_type_(msg_type),
- transid_(transid) {
-
- data_ = boost::shared_array<uint8_t>(new uint8_t[4]);
- data_len_ = 4;
+Pkt6::Pkt6(uint8_t msg_type, unsigned int transid, DHCPv6Proto proto /*= UDP*/) :
+ proto_(proto),
+ msg_type_(msg_type),
+ transid_(transid),
+ iface_(""),
+ ifindex_(-1),
+ local_addr_("::"),
+ remote_addr_("::"),
+ local_port_(-1),
+ remote_port_(-1),
+ bufferOut_(0) {
}
-unsigned short
-Pkt6::len() {
- unsigned int length = DHCPV6_PKT_HDR_LEN; // DHCPv6 header
+uint16_t Pkt6::len() {
+ uint16_t length = DHCPV6_PKT_HDR_LEN; // DHCPv6 header
for (Option::OptionCollection::iterator it = options_.begin();
it != options_.end();
@@ -95,44 +88,21 @@ Pkt6::packUDP() {
// It is better to implement a method in IOAddress that extracts
// vector<uint8_t>
- unsigned short length = len();
- if (data_len_ < length) {
- cout << "Previous len=" << data_len_ << ", allocating new buffer: len="
- << length << endl;
-
- // May throw exception if out of memory. That is rather fatal,
- // so we don't catch this
- data_ = boost::shared_array<uint8_t>(new uint8_t[length]);
- data_len_ = length;
- }
-
- data_len_ = length;
try {
// DHCPv6 header: message-type (1 octect) + transaction id (3 octets)
- data_[0] = msg_type_;
-
+ bufferOut_.writeUint8(msg_type_);
// store 3-octet transaction-id
- data_[1] = (transid_ >> 16) & 0xff;
- data_[2] = (transid_ >> 8) & 0xff;
- data_[3] = (transid_) & 0xff;
+ bufferOut_.writeUint8( (transid_ >> 16) & 0xff );
+ bufferOut_.writeUint8( (transid_ >> 8) & 0xff );
+ bufferOut_.writeUint8( (transid_) & 0xff );
// the rest are options
- unsigned short offset = LibDHCP::packOptions6(data_, length,
- 4/*offset*/,
- options_);
-
- // sanity check
- if (offset != length) {
- isc_throw(OutOfRange, "Packet build failed: expected size="
- << length << ", actual len=" << offset);
- }
+ LibDHCP::packOptions6(bufferOut_, options_);
}
catch (const Exception& e) {
cout << "Packet build failed:" << e.what() << endl;
return (false);
}
- // Limited verbosity of this method
- // cout << "Packet built, len=" << len() << endl;
return (true);
}
@@ -158,8 +128,8 @@ Pkt6::unpack() {
bool
Pkt6::unpackUDP() {
- if (data_len_ < 4) {
- std::cout << "DHCPv6 packet truncated. Only " << data_len_
+ if (data_.size() < 4) {
+ std::cout << "DHCPv6 packet truncated. Only " << data_.size()
<< " bytes. Need at least 4." << std::endl;
return (false);
}
@@ -168,16 +138,13 @@ Pkt6::unpackUDP() {
((data_[2]) << 8) + (data_[3]);
transid_ = transid_ & 0xffffff;
- unsigned int offset = LibDHCP::unpackOptions6(data_,
- data_len_,
- 4, //offset
- data_len_ - 4,
- options_);
- if (offset != data_len_) {
- cout << "DHCPv6 packet contains trailing garbage. Parsed "
- << offset << " bytes, packet is " << data_len_ << " bytes."
- << endl;
- // just a warning. Ignore trailing garbage and continue
+ try {
+ OptionBuffer opt_buffer(data_.begin() + 4, data_.end());
+
+ LibDHCP::unpackOptions6(opt_buffer, options_);
+ } catch (const Exception& e) {
+ cout << "Packet parsing failed:" << e.what() << endl;
+ return (false);
}
return (true);
}
@@ -229,4 +196,11 @@ Pkt6::delOption(unsigned short type) {
return (false); // can't find option to be deleted
}
+void Pkt6::repack() {
+ cout << "Convering RX packet to TX packet: " << data_.size() << " bytes." << endl;
+
+ bufferOut_.writeData(&data_[0], data_.size());
+}
+
+
};
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index 019eeb2..898eefc 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -41,17 +41,18 @@ public:
/// @param msg_type type of message (SOLICIT=1, ADVERTISE=2, ...)
/// @param transid transaction-id
/// @param proto protocol (TCP or UDP)
- Pkt6(unsigned char msg_type,
- unsigned int transid,
+ Pkt6(uint8_t msg_type,
+ uint32_t transid,
DHCPv6Proto proto = UDP);
/// Constructor, used in message transmission
///
/// Creates new message. Transaction-id will randomized.
///
- /// @param len size of buffer to be allocated for this packet.
+ /// @param buf pointer to a buffer of received packet content
+ /// @param len size of buffer of received packet content
/// @param proto protocol (usually UDP, but TCP will be supported eventually)
- Pkt6(unsigned int len, DHCPv6Proto proto = UDP);
+ Pkt6(const uint8_t* buf, uint32_t len, DHCPv6Proto proto = UDP);
/// @brief Prepares on-wire format.
///
@@ -61,8 +62,7 @@ public:
/// will be set in data_len_.
///
/// @return true if packing procedure was successful
- bool
- pack();
+ bool pack();
/// @brief Dispatch method that handles binary packet parsing.
///
@@ -70,59 +70,70 @@ public:
/// unpackTCP).
///
/// @return true if parsing was successful
- bool
- unpack();
+ bool unpack();
- /// Returns protocol of this packet (UDP or TCP)
+ /// @brief Returns reference to output buffer.
+ ///
+ /// Returned buffer will contain reasonable data only for
+ /// output (TX) packet and after pack() was called. This buffer
+ /// is only valid till Pkt4 object is valid.
+ ///
+ /// RX packet or TX packet before pack() will return buffer with
+ /// zero length
+ ///
+ /// @return reference to output buffer
+ const isc::util::OutputBuffer& getBuffer() const { return (bufferOut_); };
+
+
+ /// @brief Returns reference to input buffer.
+ ///
+ /// @return reference to input buffer
+ const OptionBuffer& getData() const { return(data_); }
+
+ /// @brief Returns protocol of this packet (UDP or TCP).
///
/// @return protocol type
- DHCPv6Proto
- getProto();
+ DHCPv6Proto getProto();
/// Sets protocol of this packet.
///
/// @param proto protocol (UDP or TCP)
- ///
- void
- setProto(DHCPv6Proto proto = UDP) { proto_ = proto; }
+ void setProto(DHCPv6Proto proto = UDP) { proto_ = proto; }
/// @brief Returns text representation of the packet.
///
/// This function is useful mainly for debugging.
///
/// @return string with text representation
- std::string
- toText();
+ std::string toText();
/// @brief Returns calculated length of the packet.
///
- /// This function returns size of required buffer to buld this packet.
- /// To use that function, options_ field must be set.
+ /// This function returns size of all options including DHCPv6
+ /// header. To use that function, options_ field must be set.
///
/// @return number of bytes required to build this packet
- unsigned short
- len();
+ uint16_t len();
/// Returns message type (e.g. 1 = SOLICIT)
///
/// @return message type
- unsigned char
- getType() { return (msg_type_); }
+ uint8_t getType() { return (msg_type_); }
/// Sets message type (e.g. 1 = SOLICIT)
///
/// @param type message type to be set
- void setType(unsigned char type) { msg_type_=type; };
+ void setType(uint8_t type) { msg_type_=type; };
/// Returns value of transaction-id field
///
/// @return transaction-id
- unsigned int getTransid() { return (transid_); };
+ uint32_t getTransid() { return (transid_); };
/// Adds an option to this packet.
///
/// @param opt option to be added.
- void addOption(boost::shared_ptr<isc::dhcp::Option> opt);
+ void addOption(OptionPtr opt);
/// @brief Returns the first option of specified type.
///
@@ -133,49 +144,93 @@ public:
/// @param opt_type option type we are looking for
///
/// @return pointer to found option (or NULL)
- boost::shared_ptr<isc::dhcp::Option>
- getOption(unsigned short type);
+ OptionPtr getOption(uint16_t type);
/// Attempts to delete first suboption of requested type
///
/// @param type Type of option to be deleted.
///
/// @return true if option was deleted, false if no such option existed
- bool
- delOption(unsigned short type);
+ bool delOption(uint16_t type);
- /// TODO need getter/setter wrappers
- /// and hide following fields as protected
+ /// @brief This method copies data from output buffer to input buffer
+ ///
+ /// This is useful only in testing
+ void repack();
- /// buffer that holds memory. It is shared_array as options may
- /// share pointer to this buffer
- boost::shared_array<uint8_t> data_;
+ /// @brief Sets remote address.
+ ///
+ /// @params remote specifies remote address
+ void setRemoteAddr(const isc::asiolink::IOAddress& remote) {
+ remote_addr_ = remote;
+ }
- /// length of the data
- unsigned int data_len_;
+ /// @brief Returns remote address
+ ///
+ /// @return remote address
+ const isc::asiolink::IOAddress& getRemoteAddr() {
+ return (remote_addr_);
+ }
- /// local address (dst if receiving packet, src if sending packet)
- isc::asiolink::IOAddress local_addr_;
+ /// @brief Sets local address.
+ ///
+ /// @params local specifies local address
+ void setLocalAddr(const isc::asiolink::IOAddress& local) {
+ local_addr_ = local;
+ }
- /// remote address (src if receiving packet, dst if sending packet)
- isc::asiolink::IOAddress remote_addr_;
+ /// @brief Returns local address.
+ ///
+ /// @return local address
+ const isc::asiolink::IOAddress& getLocalAddr() {
+ return (local_addr_);
+ }
- /// name of the network interface the packet was received/to be sent over
- std::string iface_;
+ /// @brief Sets local port.
+ ///
+ /// @params local specifies local port
+ void setLocalPort(uint16_t local) { local_port_ = local; }
- /// @brief interface index
+ /// @brief Returns local port.
///
- /// interface index (each network interface has assigned unique ifindex
- /// it is functional equvalent of name, but sometimes more useful, e.g.
- /// when using crazy systems that allow spaces in interface names
- /// e.g. windows
- int ifindex_;
+ /// @return local port
+ uint16_t getLocalPort() { return (local_port_); }
- /// local TDP or UDP port
- int local_port_;
+ /// @brief Sets remote port.
+ ///
+ /// @params remote specifies remote port
+ void setRemotePort(uint16_t remote) { remote_port_ = remote; }
- /// remote TCP or UDP port
- int remote_port_;
+ /// @brief Returns remote port.
+ ///
+ /// @return remote port
+ uint16_t getRemotePort() { return (remote_port_); }
+
+ /// @brief Sets interface index.
+ ///
+ /// @param ifindex specifies interface index.
+ void setIndex(uint32_t ifindex) { ifindex_ = ifindex; };
+
+ /// @brief Returns interface index.
+ ///
+ /// @return interface index
+ uint32_t getIndex() const { return (ifindex_); };
+
+ /// @brief Returns interface name.
+ ///
+ /// Returns interface name over which packet was received or is
+ /// going to be transmitted.
+ ///
+ /// @return interface name
+ std::string getIface() const { return iface_; };
+
+ /// @brief Sets interface name.
+ ///
+ /// Sets interface name over which packet was received or is
+ /// going to be transmitted.
+ ///
+ /// @return interface name
+ void setIface(const std::string& iface ) { iface_ = iface; };
/// TODO Need to implement getOptions() as well
@@ -225,8 +280,40 @@ protected:
/// DHCPv6 transaction-id
unsigned int transid_;
+
+ /// unparsed data (in received packets)
+ OptionBuffer data_;
+
+ /// name of the network interface the packet was received/to be sent over
+ std::string iface_;
+
+ /// @brief interface index
+ ///
+ /// interface index (each network interface has assigned unique ifindex
+ /// it is functional equvalent of name, but sometimes more useful, e.g.
+ /// when using crazy systems that allow spaces in interface names
+ /// e.g. windows
+ int ifindex_;
+
+ /// local address (dst if receiving packet, src if sending packet)
+ isc::asiolink::IOAddress local_addr_;
+
+ /// remote address (src if receiving packet, dst if sending packet)
+ isc::asiolink::IOAddress remote_addr_;
+
+ /// local TDP or UDP port
+ int local_port_;
+
+ /// remote TCP or UDP port
+ int remote_port_;
+
+ /// output buffer (used during message transmission)
+ isc::util::OutputBuffer bufferOut_;
+
}; // Pkt6 class
+typedef boost::shared_ptr<Pkt6> Pkt6Ptr;
+
} // isc::dhcp namespace
} // isc namespace
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index 9991e54..bfca5ac 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -263,8 +263,8 @@ TEST_F(IfaceMgrTest, sockets6) {
IOAddress loAddr("::1");
- Pkt6 pkt6(128);
- pkt6.iface_ = LOOPBACK;
+ Pkt6 pkt6(DHCPV6_SOLICIT, 123);
+ pkt6.setIface(LOOPBACK);
// bind multicast socket to port 10547
int socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
@@ -335,19 +335,22 @@ TEST_F(IfaceMgrTest, sendReceive6) {
EXPECT_GT(socket1, 0);
EXPECT_GT(socket2, 0);
- boost::shared_ptr<Pkt6> sendPkt(new Pkt6(128) );
// prepare dummy payload
+ uint8_t data[128];
for (int i=0;i<128; i++) {
- sendPkt->data_[i] = i;
+ data[i] = i;
}
+ Pkt6Ptr sendPkt = Pkt6Ptr(new Pkt6(data, 128));
- sendPkt->remote_port_ = 10547;
- sendPkt->remote_addr_ = IOAddress("::1");
- sendPkt->ifindex_ = 1;
- sendPkt->iface_ = LOOPBACK;
+ sendPkt->repack();
- boost::shared_ptr<Pkt6> rcvPkt;
+ sendPkt->setRemotePort(10547);
+ sendPkt->setRemoteAddr(IOAddress("::1"));
+ sendPkt->setIndex(1);
+ sendPkt->setIface(LOOPBACK);
+
+ Pkt6Ptr rcvPkt;
EXPECT_EQ(true, ifacemgr->send(sendPkt));
@@ -356,17 +359,17 @@ TEST_F(IfaceMgrTest, sendReceive6) {
ASSERT_TRUE( rcvPkt ); // received our own packet
// let's check that we received what was sent
- EXPECT_EQ(sendPkt->data_len_, rcvPkt->data_len_);
- EXPECT_EQ(0, memcmp(&sendPkt->data_[0], &rcvPkt->data_[0],
- rcvPkt->data_len_) );
+ ASSERT_EQ(sendPkt->getData().size(), rcvPkt->getData().size());
+ EXPECT_EQ(0, memcmp(&sendPkt->getData()[0], &rcvPkt->getData()[0],
+ rcvPkt->getData().size()));
- EXPECT_EQ(sendPkt->remote_addr_.toText(), rcvPkt->remote_addr_.toText());
+ EXPECT_EQ(sendPkt->getRemoteAddr().toText(), rcvPkt->getRemoteAddr().toText());
// since we opened 2 sockets on the same interface and none of them is multicast,
// none is preferred over the other for sending data, so we really should not
// assume the one or the other will always be choosen for sending data. Therefore
// we should accept both values as source ports.
- EXPECT_TRUE( (rcvPkt->remote_port_ == 10546) || (rcvPkt->remote_port_ == 10547) );
+ EXPECT_TRUE( (rcvPkt->getRemotePort() == 10546) || (rcvPkt->getRemotePort() == 10547) );
delete ifacemgr;
}
@@ -556,7 +559,7 @@ TEST_F(IfaceMgrTest, socketInfo) {
loopback->addSocket(sock1);
loopback->addSocket(sock2);
- Pkt6 pkt6(100);
+ Pkt6 pkt6(DHCPV6_REPLY, 123456);
// pkt6 dos not have interface set yet
EXPECT_THROW(
@@ -565,14 +568,14 @@ TEST_F(IfaceMgrTest, socketInfo) {
);
// try to send over non-existing interface
- pkt6.iface_ = "nosuchinterface45";
+ pkt6.setIface("nosuchinterface45");
EXPECT_THROW(
ifacemgr->getSocket(pkt6),
BadValue
);
// this will work
- pkt6.iface_ = LOOPBACK;
+ pkt6.setIface(LOOPBACK);
EXPECT_EQ(9, ifacemgr->getSocket(pkt6));
bool deleted = false;
diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc
index ee3b873..33712a4 100644
--- a/src/lib/dhcp/tests/libdhcp++_unittest.cc
+++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -42,7 +42,7 @@ static const uint8_t packed[] = {
};
TEST(LibDhcpTest, packOptions6) {
- boost::shared_array<uint8_t> buf(new uint8_t[512]);
+ OptionBuffer buf(512);
isc::dhcp::Option::OptionCollection opts; // list of options
// generate content for options
@@ -50,24 +50,25 @@ TEST(LibDhcpTest, packOptions6) {
buf[i]=i+100;
}
- boost::shared_ptr<Option> opt1(new Option(Option::V6, 12, buf, 0, 5));
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 13, buf, 5, 3));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 14, buf, 8, 2));
- boost::shared_ptr<Option> opt4(new Option(Option::V6,256, buf,10, 4));
- boost::shared_ptr<Option> opt5(new Option(Option::V6,257, buf,14, 1));
+ OptionPtr opt1(new Option(Option::V6, 12, buf.begin() + 0, buf.begin() + 5));
+ OptionPtr opt2(new Option(Option::V6, 13, buf.begin() + 5, buf.begin() + 8));
+ OptionPtr opt3(new Option(Option::V6, 14, buf.begin() + 8, buf.begin() + 10));
+ OptionPtr opt4(new Option(Option::V6,256, buf.begin() + 10,buf.begin() + 14));
+ OptionPtr opt5(new Option(Option::V6,257, buf.begin() + 14,buf.begin() + 15));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt1));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt2));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt3));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt4));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt5));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt1));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt2));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt3));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt4));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt5));
+
+ OutputBuffer assembled(512);
- unsigned int offset;
EXPECT_NO_THROW ({
- offset = LibDHCP::packOptions6(buf, 512, 100, opts);
+ LibDHCP::packOptions6(assembled, opts);
});
- EXPECT_EQ(135, offset); // options should take 35 bytes
- EXPECT_EQ(0, memcmp(&buf[100], packed, 35) );
+ EXPECT_EQ(35, assembled.getLength()); // options should take 35 bytes
+ EXPECT_EQ(0, memcmp(assembled.getData(), packed, 35) );
}
TEST(LibDhcpTest, unpackOptions6) {
@@ -78,17 +79,13 @@ TEST(LibDhcpTest, unpackOptions6) {
// specific derived classes.
isc::dhcp::Option::OptionCollection options; // list of options
- // we can't use packed directly, as shared_array would try to
- // free it eventually
- boost::shared_array<uint8_t> buf(new uint8_t[512]);
+ OptionBuffer buf(512);
memcpy(&buf[0], packed, 35);
- unsigned int offset;
EXPECT_NO_THROW ({
- offset = LibDHCP::unpackOptions6(buf, 512, 0, 35, options);
+ LibDHCP::unpackOptions6(OptionBuffer(buf.begin(), buf.begin()+35), options);
});
- EXPECT_EQ(35, offset); // parsed first 35 bytes (offset 0..34)
EXPECT_EQ(options.size(), 5); // there should be 5 options
isc::dhcp::Option::OptionCollection::const_iterator x = options.find(12);
@@ -153,18 +150,18 @@ TEST(LibDhcpTest, packOptions4) {
payload[i][2] = i*10+2;
}
- boost::shared_ptr<Option> opt1(new Option(Option::V4, 12, payload[0]));
- boost::shared_ptr<Option> opt2(new Option(Option::V4, 13, payload[1]));
- boost::shared_ptr<Option> opt3(new Option(Option::V4, 14, payload[2]));
- boost::shared_ptr<Option> opt4(new Option(Option::V4,254, payload[3]));
- boost::shared_ptr<Option> opt5(new Option(Option::V4,128, payload[4]));
+ OptionPtr opt1(new Option(Option::V4, 12, payload[0]));
+ OptionPtr opt2(new Option(Option::V4, 13, payload[1]));
+ OptionPtr opt3(new Option(Option::V4, 14, payload[2]));
+ OptionPtr opt4(new Option(Option::V4,254, payload[3]));
+ OptionPtr opt5(new Option(Option::V4,128, payload[4]));
isc::dhcp::Option::OptionCollection opts; // list of options
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt1));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt2));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt3));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt4));
- opts.insert(pair<int, boost::shared_ptr<Option> >(opt1->getType(), opt5));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt1));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt2));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt3));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt4));
+ opts.insert(pair<int, OptionPtr >(opt1->getType(), opt5));
vector<uint8_t> expVect(v4Opts, v4Opts + sizeof(v4Opts));
diff --git a/src/lib/dhcp/tests/option6_addrlst_unittest.cc b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
index 60b618b..040cc70 100644
--- a/src/lib/dhcp/tests/option6_addrlst_unittest.cc
+++ b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -21,17 +21,24 @@
#include <dhcp/dhcp6.h>
#include <dhcp/option.h>
#include <dhcp/option6_addrlst.h>
+#include <util/buffer.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::asiolink;
+using namespace isc::util;
namespace {
class Option6AddrLstTest : public ::testing::Test {
public:
- Option6AddrLstTest() {
+ Option6AddrLstTest(): buf_(255), outBuf_(255) {
+ for (int i = 0; i < 255; i++) {
+ buf_[i] = 255 - i;
+ }
}
+ OptionBuffer buf_;
+ OutputBuffer outBuf_;
};
TEST_F(Option6AddrLstTest, basic) {
@@ -97,16 +104,12 @@ TEST_F(Option6AddrLstTest, basic) {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
- boost::shared_array<uint8_t> buf(new uint8_t[300]);
- for (int i = 0; i < 300; i++)
- buf[i] = 0;
-
- memcpy(&buf[0], sampledata, 48);
+ memcpy(&buf_[0], sampledata, 48);
// just a single address
Option6AddrLst* opt1 = 0;
EXPECT_NO_THROW(
- opt1 = new Option6AddrLst(D6O_NAME_SERVERS, buf, 128, 0, 16);
+ opt1 = new Option6AddrLst(D6O_NAME_SERVERS, buf_.begin(), buf_.begin() + 16 );
);
EXPECT_EQ(Option::V6, opt1->getUniverse());
@@ -118,17 +121,16 @@ TEST_F(Option6AddrLstTest, basic) {
IOAddress addr = addrs[0];
EXPECT_EQ("2001:db8:1::dead:beef", addr.toText());
- // pack this option again in the same buffer, but in
- // different place
- int offset = opt1->pack(buf,300, 100);
+ // pack this option
+ opt1->pack(outBuf_);
- EXPECT_EQ(120, offset);
- EXPECT_EQ( 0, memcmp(expected1, &buf[100], 20) );
+ EXPECT_EQ(20, outBuf_.getLength());
+ EXPECT_EQ( 0, memcmp(expected1, outBuf_.getData(), 20) );
// two addresses
Option6AddrLst* opt2 = 0;
EXPECT_NO_THROW(
- opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR, buf, 128, 0, 32);
+ opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR, buf_.begin(), buf_.begin() + 32);
);
EXPECT_EQ(D6O_SIP_SERVERS_ADDR, opt2->getType());
EXPECT_EQ(36, opt2->len());
@@ -137,17 +139,17 @@ TEST_F(Option6AddrLstTest, basic) {
EXPECT_EQ("2001:db8:1::dead:beef", addrs[0].toText());
EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
- // pack this option again in the same buffer, but in
- // different place
- offset = opt2->pack(buf,300, 150);
+ // pack this option
+ outBuf_.clear();
+ opt2->pack(outBuf_);
- EXPECT_EQ(150+36, offset);
- EXPECT_EQ( 0, memcmp(expected2, &buf[150], 36));
+ EXPECT_EQ(36, outBuf_.getLength() );
+ EXPECT_EQ( 0, memcmp(expected2, outBuf_.getData(), 36));
// three addresses
Option6AddrLst* opt3 = 0;
EXPECT_NO_THROW(
- opt3 = new Option6AddrLst(D6O_NIS_SERVERS, buf, 128, 0, 48);
+ opt3 = new Option6AddrLst(D6O_NIS_SERVERS, buf_.begin(), buf_.begin() + 48);
);
EXPECT_EQ(D6O_NIS_SERVERS, opt3->getType());
@@ -158,12 +160,12 @@ TEST_F(Option6AddrLstTest, basic) {
EXPECT_EQ("ff02::face:b00c", addrs[1].toText());
EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", addrs[2].toText());
- // pack this option again in the same buffer, but in
- // different place
- offset = opt3->pack(buf,300, 200);
+ // pack this option
+ outBuf_.clear();
+ opt3->pack(outBuf_);
- EXPECT_EQ(252, offset);
- EXPECT_EQ( 0, memcmp(expected3, &buf[200], 52) );
+ EXPECT_EQ(52, outBuf_.getLength());
+ EXPECT_EQ( 0, memcmp(expected3, outBuf_.getData(), 52) );
EXPECT_NO_THROW(
delete opt1;
diff --git a/src/lib/dhcp/tests/option6_ia_unittest.cc b/src/lib/dhcp/tests/option6_ia_unittest.cc
index 3fd52f5..08a3567 100644
--- a/src/lib/dhcp/tests/option6_ia_unittest.cc
+++ b/src/lib/dhcp/tests/option6_ia_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -19,53 +19,51 @@
#include <arpa/inet.h>
#include <gtest/gtest.h>
-#include <boost/shared_array.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include "dhcp/dhcp6.h"
-#include "dhcp/option.h"
-#include "dhcp/option6_ia.h"
-#include "dhcp/option6_iaaddr.h"
+#include <dhcp/dhcp6.h>
+#include <dhcp/option.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/option6_iaaddr.h>
+#include <util/buffer.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::asiolink;
+using namespace isc::util;
namespace {
class Option6IATest : public ::testing::Test {
public:
- Option6IATest() {
+ Option6IATest(): buf_(255), outBuf_(255) {
+ for (int i = 0; i < 255; i++) {
+ buf_[i] = 255 - i;
+ }
}
+ OptionBuffer buf_;
+ OutputBuffer outBuf_;
};
TEST_F(Option6IATest, basic) {
+ buf_[0] = 0xa1; // iaid
+ buf_[1] = 0xa2;
+ buf_[2] = 0xa3;
+ buf_[3] = 0xa4;
- boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
- for (int i = 0; i < 128; i++)
- simple_buf[i] = 0;
- simple_buf[0] = 0xa1; // iaid
- simple_buf[1] = 0xa2;
- simple_buf[2] = 0xa3;
- simple_buf[3] = 0xa4;
-
- simple_buf[4] = 0x81; // T1
- simple_buf[5] = 0x02;
- simple_buf[6] = 0x03;
- simple_buf[7] = 0x04;
+ buf_[4] = 0x81; // T1
+ buf_[5] = 0x02;
+ buf_[6] = 0x03;
+ buf_[7] = 0x04;
- simple_buf[8] = 0x84; // T2
- simple_buf[9] = 0x03;
- simple_buf[10] = 0x02;
- simple_buf[11] = 0x01;
+ buf_[8] = 0x84; // T2
+ buf_[9] = 0x03;
+ buf_[10] = 0x02;
+ buf_[11] = 0x01;
// create an option
// unpack() is called from constructor
Option6IA* opt = new Option6IA(D6O_IA_NA,
- simple_buf,
- 128,
- 0,
- 12);
+ buf_.begin(),
+ buf_.begin() + 12);
EXPECT_EQ(Option::V6, opt->getUniverse());
EXPECT_EQ(D6O_IA_NA, opt->getType());
@@ -77,36 +75,31 @@ TEST_F(Option6IATest, basic) {
// different place
// test for pack()
- int offset = opt->pack(simple_buf, 128, 60);
+ opt->pack(outBuf_);
- // 4 bytes header + 4 bytes content
- EXPECT_EQ(12, opt->len() - 4);
+ // 12 bytes header + 4 bytes content
+ EXPECT_EQ(12, opt->len() - opt->getHeaderLen());
EXPECT_EQ(D6O_IA_NA, opt->getType());
- EXPECT_EQ(offset, 76); // 60 + lenght(IA_NA) = 76
+ EXPECT_EQ(16, outBuf_.getLength()); // lenght(IA_NA) = 16
// check if pack worked properly:
+ InputBuffer out(outBuf_.getData(), outBuf_.getLength());
+
// if option type is correct
- EXPECT_EQ(D6O_IA_NA, simple_buf[60]*256 + simple_buf[61]);
+ EXPECT_EQ(D6O_IA_NA, out.readUint16());
// if option length is correct
- EXPECT_EQ(12, simple_buf[62]*256 + simple_buf[63]);
+ EXPECT_EQ(12, out.readUint16());
// if iaid is correct
- unsigned int iaid = htonl(*(unsigned int*)&simple_buf[64]);
- EXPECT_EQ(0xa1a2a3a4, iaid );
+ EXPECT_EQ(0xa1a2a3a4, out.readUint32() );
// if T1 is correct
- EXPECT_EQ(0x81020304, (simple_buf[68] << 24) +
- (simple_buf[69] << 16) +
- (simple_buf[70] << 8) +
- (simple_buf[71]) );
+ EXPECT_EQ(0x81020304, out.readUint32() );
// if T1 is correct
- EXPECT_EQ(0x84030201, (simple_buf[72] << 24) +
- (simple_buf[73] << 16) +
- (simple_buf[74] << 8) +
- (simple_buf[75]) );
+ EXPECT_EQ(0x84030201, out.readUint32() );
EXPECT_NO_THROW(
delete opt;
@@ -114,10 +107,6 @@ TEST_F(Option6IATest, basic) {
}
TEST_F(Option6IATest, simple) {
- boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
- for (int i = 0; i < 128; i++)
- simple_buf[i] = 0;
-
Option6IA * ia = new Option6IA(D6O_IA_NA, 1234);
ia->setT1(2345);
ia->setT2(3456);
@@ -133,20 +122,18 @@ TEST_F(Option6IATest, simple) {
);
}
+
// test if option can build suboptions
TEST_F(Option6IATest, suboptions_pack) {
- boost::shared_array<uint8_t> buf(new uint8_t[128]);
- for (int i=0; i<128; i++)
- buf[i] = 0;
- buf[0] = 0xff;
- buf[1] = 0xfe;
- buf[2] = 0xfc;
+ buf_[0] = 0xff;
+ buf_[1] = 0xfe;
+ buf_[2] = 0xfc;
Option6IA * ia = new Option6IA(D6O_IA_NA, 0x13579ace);
ia->setT1(0x2345);
ia->setT2(0x3456);
- boost::shared_ptr<Option> sub1(new Option(Option::V6,
+ OptionPtr sub1(new Option(Option::V6,
0xcafe));
boost::shared_ptr<Option6IAAddr> addr1(
@@ -180,20 +167,20 @@ TEST_F(Option6IATest, suboptions_pack) {
0, 0 // len
};
- int offset = ia->pack(buf, 128, 10);
- ASSERT_EQ(offset, 10 + 48);
+ ia->pack(outBuf_);
+ ASSERT_EQ(48, outBuf_.getLength());
- EXPECT_EQ(0, memcmp(&buf[10], expected, 48));
+ EXPECT_EQ(0, memcmp(outBuf_.getData(), expected, 48));
EXPECT_NO_THROW(
delete ia;
);
}
+
// test if option can parse suboptions
TEST_F(Option6IATest, suboptions_unpack) {
-
-
+ // 48 bytes
uint8_t expected[] = {
D6O_IA_NA/256, D6O_IA_NA%256, // type
0, 28, // length
@@ -214,17 +201,11 @@ TEST_F(Option6IATest, suboptions_unpack) {
0, 0 // len
};
- boost::shared_array<uint8_t> buf(new uint8_t[128]);
- for (int i = 0; i < 128; i++)
- buf[i] = 0;
- memcpy(&buf[0], expected, 48);
+ memcpy(&buf_[0], expected, sizeof(expected));
Option6IA* ia = 0;
EXPECT_NO_THROW({
- ia = new Option6IA(D6O_IA_NA, buf, 128, 4, 44);
-
- // let's limit verbosity of this test
- // cout << "Parsed option:" << endl << ia->toText() << endl;
+ ia = new Option6IA(D6O_IA_NA, buf_.begin() + 4, buf_.begin() + sizeof(expected));
});
ASSERT_TRUE(ia);
@@ -233,8 +214,8 @@ TEST_F(Option6IATest, suboptions_unpack) {
EXPECT_EQ(0x2345, ia->getT1());
EXPECT_EQ(0x3456, ia->getT2());
- boost::shared_ptr<Option> subopt = ia->getOption(D6O_IAADDR);
- ASSERT_NE(boost::shared_ptr<Option>(), subopt); // non-NULL
+ OptionPtr subopt = ia->getOption(D6O_IAADDR);
+ ASSERT_NE(OptionPtr(), subopt); // non-NULL
// checks for address option
Option6IAAddr * addr = dynamic_cast<Option6IAAddr*>(subopt.get());
diff --git a/src/lib/dhcp/tests/option6_iaaddr_unittest.cc b/src/lib/dhcp/tests/option6_iaaddr_unittest.cc
index 81c3eb3..a6f763f 100644
--- a/src/lib/dhcp/tests/option6_iaaddr_unittest.cc
+++ b/src/lib/dhcp/tests/option6_iaaddr_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -19,61 +19,62 @@
#include <arpa/inet.h>
#include <gtest/gtest.h>
-#include "dhcp/dhcp6.h"
-#include "dhcp/option.h"
-#include "dhcp/option6_iaaddr.h"
+#include <dhcp/dhcp6.h>
+#include <dhcp/option.h>
+#include <dhcp/option6_iaaddr.h>
+#include <util/buffer.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
+using namespace isc::util;
namespace {
class Option6IAAddrTest : public ::testing::Test {
public:
- Option6IAAddrTest() {
+ Option6IAAddrTest() : buf_(255), outBuf_(255) {
+ for (int i = 0; i < 255; i++) {
+ buf_[i] = 255 - i;
+ }
}
+ OptionBuffer buf_;
+ OutputBuffer outBuf_;
};
-/// TODO reenable this once ticket #1313 is implemented.
TEST_F(Option6IAAddrTest, basic) {
-
- boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
- for (int i = 0; i < 128; i++)
- simple_buf[i] = 0;
-
- simple_buf[0] = 0x20;
- simple_buf[1] = 0x01;
- simple_buf[2] = 0x0d;
- simple_buf[3] = 0xb8;
- simple_buf[4] = 0x00;
- simple_buf[5] = 0x01;
- simple_buf[12] = 0xde;
- simple_buf[13] = 0xad;
- simple_buf[14] = 0xbe;
- simple_buf[15] = 0xef; // 2001:db8:1::dead:beef
-
- simple_buf[16] = 0x00;
- simple_buf[17] = 0x00;
- simple_buf[18] = 0x03;
- simple_buf[19] = 0xe8; // 1000
-
- simple_buf[20] = 0xb2;
- simple_buf[21] = 0xd0;
- simple_buf[22] = 0x5e;
- simple_buf[23] = 0x00; // 3,000,000,000
+ for (int i=0; i<255; i++) {
+ buf_[i]=0;
+ }
+ buf_[0] = 0x20;
+ buf_[1] = 0x01;
+ buf_[2] = 0x0d;
+ buf_[3] = 0xb8;
+ buf_[4] = 0x00;
+ buf_[5] = 0x01;
+ buf_[12] = 0xde;
+ buf_[13] = 0xad;
+ buf_[14] = 0xbe;
+ buf_[15] = 0xef; // 2001:db8:1::dead:beef
+
+ buf_[16] = 0x00;
+ buf_[17] = 0x00;
+ buf_[18] = 0x03;
+ buf_[19] = 0xe8; // 1000
+
+ buf_[20] = 0xb2;
+ buf_[21] = 0xd0;
+ buf_[22] = 0x5e;
+ buf_[23] = 0x00; // 3,000,000,000
// create an option (unpack content)
Option6IAAddr* opt = new Option6IAAddr(D6O_IAADDR,
- simple_buf,
- 128,
- 0,
- 24);
+ buf_.begin(),
+ buf_.begin() + 24);
- // pack this option again in the same buffer, but in
- // different place
- int offset = opt->pack(simple_buf, 128, 50);
+ // pack this option
+ opt->pack(outBuf_);
- EXPECT_EQ(78, offset);
+ EXPECT_EQ(28, outBuf_.getLength());
EXPECT_EQ(Option::V6, opt->getUniverse());
@@ -88,14 +89,16 @@ TEST_F(Option6IAAddrTest, basic) {
opt->len());
// check if pack worked properly:
+ const uint8_t* out = (const uint8_t*)outBuf_.getData();
+
// if option type is correct
- EXPECT_EQ(D6O_IAADDR, simple_buf[50]*256 + simple_buf[51]);
+ EXPECT_EQ(D6O_IAADDR, out[0]*256 + out[1]);
// if option length is correct
- EXPECT_EQ(24, simple_buf[52]*256 + simple_buf[53]);
+ EXPECT_EQ(24, out[2]*256 + out[3]);
// if option content is correct
- EXPECT_EQ(0, memcmp(&simple_buf[0], &simple_buf[54],24));
+ EXPECT_EQ(0, memcmp(out + 4, &buf_[0], 24));
EXPECT_NO_THROW(
delete opt;
diff --git a/src/lib/dhcp/tests/option_unittest.cc b/src/lib/dhcp/tests/option_unittest.cc
index c83a839..265da28 100644
--- a/src/lib/dhcp/tests/option_unittest.cc
+++ b/src/lib/dhcp/tests/option_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -33,14 +33,13 @@ using namespace isc::util;
namespace {
class OptionTest : public ::testing::Test {
public:
- OptionTest(): outBuffer_(255) {
- buf_ = boost::shared_array<uint8_t>(new uint8_t[255]);
+ OptionTest(): buf_(255), outBuf_(255) {
for (int i = 0; i < 255; i++) {
buf_[i] = 255 - i;
}
}
- boost::shared_array<uint8_t> buf_;
- OutputBuffer outBuffer_;
+ OptionBuffer buf_;
+ OutputBuffer outBuf_;
};
// v4 is not really implemented yet. A simple test will do for now
@@ -84,9 +83,7 @@ TEST_F(OptionTest, v4_data1) {
// create DHCPv4 option of type 123
// that contains 4 bytes of data
ASSERT_NO_THROW(
- opt= new Option(Option::V4,
- 123, // type
- data);
+ opt= new Option(Option::V4, 123, data);
);
// check that content is reported properly
@@ -143,10 +140,7 @@ TEST_F(OptionTest, v4_data2) {
// Create DHCPv4 option of type 123 that contains
// 4 bytes (sizeof(dummyPayload).
ASSERT_NO_THROW(
- opt= new Option(Option::V4,
- 123, // type
- data.begin() + 1,
- data.end() - 1);
+ opt= new Option(Option::V4, 123, data.begin() + 1, data.end() - 1);
);
// check that content is reported properly
@@ -210,30 +204,29 @@ TEST_F(OptionTest, v6_basic) {
// tests contructor used in pkt reception
// option contains actual data
TEST_F(OptionTest, v6_data1) {
- boost::shared_array<uint8_t> buf(new uint8_t[32]);
for (int i = 0; i < 32; i++)
- buf[i] = 100+i;
- Option* opt = new Option(Option::V6, 333, //type
- buf,
- 3, // offset
- 7); // 7 bytes of data
+ buf_[i] = 100+i;
+ Option* opt = new Option(Option::V6, 333, //type
+ buf_.begin() + 3, // begin offset
+ buf_.begin() + 10); // end offset (7 bytes of data)
EXPECT_EQ(333, opt->getType());
ASSERT_EQ(11, opt->len());
ASSERT_EQ(7, opt->getData().size());
- EXPECT_EQ(0, memcmp(&buf[3], &opt->getData()[0], 7) );
+ EXPECT_EQ(0, memcmp(&buf_[3], &opt->getData()[0], 7) );
- int offset = opt->pack(buf, 32, 20);
- EXPECT_EQ(31, offset);
+ opt->pack(outBuf_);
+ EXPECT_EQ(11, outBuf_.getLength());
- EXPECT_EQ(buf[20], 333/256); // type
- EXPECT_EQ(buf[21], 333%256);
+ const uint8_t* out = (const uint8_t*)outBuf_.getData();
+ EXPECT_EQ(out[0], 333/256); // type
+ EXPECT_EQ(out[1], 333%256);
- EXPECT_EQ(buf[22], 0); // len
- EXPECT_EQ(buf[23], 7);
+ EXPECT_EQ(out[2], 0); // len
+ EXPECT_EQ(out[3], 7);
// payload
- EXPECT_EQ(0, memcmp(&buf[3], &buf[24], 7) );
+ EXPECT_EQ(0, memcmp(&buf_[3], out+4, 7) );
EXPECT_NO_THROW(
delete opt;
@@ -244,40 +237,37 @@ TEST_F(OptionTest, v6_data1) {
// with different input parameters
TEST_F(OptionTest, v6_data2) {
- boost::shared_array<uint8_t> simple_buf(new uint8_t[128]);
- for (int i = 0; i < 128; i++)
- simple_buf[i] = 0;
- simple_buf[0] = 0xa1;
- simple_buf[1] = 0xa2;
- simple_buf[2] = 0xa3;
- simple_buf[3] = 0xa4;
+ buf_[0] = 0xa1;
+ buf_[1] = 0xa2;
+ buf_[2] = 0xa3;
+ buf_[3] = 0xa4;
// create an option (unpack content)
Option* opt = new Option(Option::V6,
D6O_CLIENTID,
- simple_buf,
- 0,
- 4);
+ buf_.begin(),
+ buf_.begin() + 4);
- // pack this option again in the same buffer, but in
- // different place
- int offset18 = opt->pack(simple_buf, 128, 10);
+ // pack this option
+ opt->pack(outBuf_);
// 4 bytes header + 4 bytes content
EXPECT_EQ(8, opt->len());
EXPECT_EQ(D6O_CLIENTID, opt->getType());
- EXPECT_EQ(offset18, 18);
+ EXPECT_EQ(8, outBuf_.getLength());
// check if pack worked properly:
// if option type is correct
- EXPECT_EQ(D6O_CLIENTID, simple_buf[10]*256 + simple_buf[11]);
+ const uint8_t* out = (const uint8_t*)outBuf_.getData();
+
+ EXPECT_EQ(D6O_CLIENTID, out[0]*256 + out[1]);
// if option length is correct
- EXPECT_EQ(4, simple_buf[12]*256 + simple_buf[13]);
+ EXPECT_EQ(4, out[2]*256 + out[3]);
// if option content is correct
- EXPECT_EQ(0, memcmp(&simple_buf[0], &simple_buf[14],4));
+ EXPECT_EQ(0, memcmp(&buf_[0], out + 4, 4));
EXPECT_NO_THROW(
delete opt;
@@ -291,18 +281,15 @@ TEST_F(OptionTest, v6_data2) {
// +----opt3
//
TEST_F(OptionTest, v6_suboptions1) {
- boost::shared_array<uint8_t> buf(new uint8_t[128]);
for (int i=0; i<128; i++)
- buf[i] = 100+i;
+ buf_[i] = 100+i;
Option* opt1 = new Option(Option::V6, 65535, //type
- buf,
- 0, // offset
- 3); // 3 bytes of data
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
- buf,
- 3, // offset
- 5)); // 5 bytes of data
+ buf_.begin(), // 3 bytes of data
+ buf_.begin() + 3);
+ OptionPtr opt2(new Option(Option::V6, 13));
+ OptionPtr opt3(new Option(Option::V6, 7,
+ buf_.begin() + 3,
+ buf_.begin() + 8)); // 5 bytes of data
opt1->addOption(opt2);
opt1->addOption(opt3);
// opt2 len = 4 (just header)
@@ -319,11 +306,11 @@ TEST_F(OptionTest, v6_suboptions1) {
0, 13, 0, 0 // no data at all
};
- int offset = opt1->pack(buf, 128, 20);
- EXPECT_EQ(40, offset);
+ opt1->pack(outBuf_);
+ EXPECT_EQ(20, outBuf_.getLength());
// payload
- EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
+ EXPECT_EQ(0, memcmp(outBuf_.getData(), expected, 20) );
EXPECT_NO_THROW(
delete opt1;
@@ -337,18 +324,15 @@ TEST_F(OptionTest, v6_suboptions1) {
// +----opt3
//
TEST_F(OptionTest, v6_suboptions2) {
- boost::shared_array<uint8_t> buf(new uint8_t[128]);
for (int i=0; i<128; i++)
- buf[i] = 100+i;
+ buf_[i] = 100+i;
Option* opt1 = new Option(Option::V6, 65535, //type
- buf,
- 0, // offset
- 3); // 3 bytes of data
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 13));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 7,
- buf,
- 3, // offset
- 5)); // 5 bytes of data
+ buf_.begin(),
+ buf_.begin() + 3);
+ OptionPtr opt2(new Option(Option::V6, 13));
+ OptionPtr opt3(new Option(Option::V6, 7,
+ buf_.begin() + 3,
+ buf_.begin() + 8));
opt1->addOption(opt2);
opt2->addOption(opt3);
// opt3 len = 9 4(header)+5(data)
@@ -361,11 +345,11 @@ TEST_F(OptionTest, v6_suboptions2) {
0, 7, 0, 5, 103, 104, 105, 106, 107,
};
- int offset = opt1->pack(buf, 128, 20);
- EXPECT_EQ(40, offset);
+ opt1->pack(outBuf_);
+ EXPECT_EQ(20, outBuf_.getLength());
// payload
- EXPECT_EQ(0, memcmp(&buf[20], expected, 20) );
+ EXPECT_EQ(0, memcmp(outBuf_.getData(), expected, 20) );
EXPECT_NO_THROW(
delete opt1;
@@ -373,13 +357,12 @@ TEST_F(OptionTest, v6_suboptions2) {
}
TEST_F(OptionTest, v6_addgetdel) {
- boost::shared_array<uint8_t> buf(new uint8_t[128]);
for (int i=0; i<128; i++)
- buf[i] = 100+i;
+ buf_[i] = 100+i;
Option* parent = new Option(Option::V6, 65535); //type
- 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));
+ OptionPtr opt1(new Option(Option::V6, 1));
+ OptionPtr opt2(new Option(Option::V6, 2));
+ OptionPtr opt3(new Option(Option::V6, 2));
parent->addOption(opt1);
parent->addOption(opt2);
@@ -389,7 +372,7 @@ TEST_F(OptionTest, v6_addgetdel) {
EXPECT_EQ(opt2, parent->getOption(2));
// expect NULL
- EXPECT_EQ(boost::shared_ptr<Option>(), parent->getOption(4));
+ EXPECT_EQ(OptionPtr(), parent->getOption(4));
// now there are 2 options of type 2
parent->addOption(opt3);
@@ -398,13 +381,13 @@ TEST_F(OptionTest, v6_addgetdel) {
EXPECT_EQ(true, parent->delOption(2));
// there still should be the other option 2
- EXPECT_NE(boost::shared_ptr<Option>(), parent->getOption(2));
+ EXPECT_NE(OptionPtr(), 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));
+ EXPECT_EQ(OptionPtr(), parent->getOption(2));
// let's try to delete - should fail
EXPECT_TRUE(false == parent->delOption(2));
@@ -412,36 +395,31 @@ TEST_F(OptionTest, v6_addgetdel) {
delete parent;
}
-}
-
TEST_F(OptionTest, v6_toText) {
- boost::shared_array<uint8_t> buf(new uint8_t[3]);
- buf[0] = 0;
- buf[1] = 0xf;
- buf[2] = 0xff;
+ buf_[0] = 0;
+ buf_[1] = 0xf;
+ buf_[2] = 0xff;
- boost::shared_ptr<Option> opt(new Option(Option::V6, 258,
- buf, 0, 3));
+ OptionPtr opt(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 3 ));
EXPECT_EQ("type=258, len=3: 00:0f:ff", opt->toText());
}
+
TEST_F(OptionTest, getUintX) {
- // TODO: Update this test to use buf_ instead of buf
- boost::shared_array<uint8_t> buf(new uint8_t[5]);
- buf[0] = 0x5;
- buf[1] = 0x4;
- buf[2] = 0x3;
- buf[3] = 0x2;
- buf[4] = 0x1;
+ buf_[0] = 0x5;
+ buf_[1] = 0x4;
+ buf_[2] = 0x3;
+ buf_[3] = 0x2;
+ buf_[4] = 0x1;
// five options with varying lengths
- boost::shared_ptr<Option> opt1(new Option(Option::V6, 258, buf, 0, 1));
- boost::shared_ptr<Option> opt2(new Option(Option::V6, 258, buf, 0, 2));
- boost::shared_ptr<Option> opt3(new Option(Option::V6, 258, buf, 0, 3));
- boost::shared_ptr<Option> opt4(new Option(Option::V6, 258, buf, 0, 4));
- boost::shared_ptr<Option> opt5(new Option(Option::V6, 258, buf, 0, 5));
+ OptionPtr opt1(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 1));
+ OptionPtr opt2(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 2));
+ OptionPtr opt3(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 3));
+ OptionPtr opt4(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 4));
+ OptionPtr opt5(new Option(Option::V6, 258, buf_.begin(), buf_.begin() + 5));
EXPECT_EQ(5, opt1->getUint8());
EXPECT_THROW(opt1->getUint16(), OutOfRange);
@@ -467,36 +445,37 @@ TEST_F(OptionTest, getUintX) {
}
TEST_F(OptionTest, setUintX) {
- boost::shared_ptr<Option> opt1(new Option(Option::V4, 125));
- boost::shared_ptr<Option> opt2(new Option(Option::V4, 125));
- boost::shared_ptr<Option> opt4(new Option(Option::V4, 125));
+ OptionPtr opt1(new Option(Option::V4, 125));
+ OptionPtr opt2(new Option(Option::V4, 125));
+ OptionPtr opt4(new Option(Option::V4, 125));
// verify setUint8
opt1->setUint8(255);
EXPECT_EQ(255, opt1->getUint8());
- opt1->pack4(outBuffer_);
+ opt1->pack4(outBuf_);
EXPECT_EQ(3, opt1->len());
- EXPECT_EQ(3, outBuffer_.getLength());
+ EXPECT_EQ(3, outBuf_.getLength());
uint8_t exp1[] = {125, 1, 255};
- EXPECT_TRUE(0 == memcmp(exp1, outBuffer_.getData(), 3));
+ EXPECT_TRUE(0 == memcmp(exp1, outBuf_.getData(), 3));
// verify getUint16
- outBuffer_.clear();
+ outBuf_.clear();
opt2->setUint16(12345);
- opt2->pack4(outBuffer_);
+ opt2->pack4(outBuf_);
EXPECT_EQ(12345, opt2->getUint16());
EXPECT_EQ(4, opt2->len());
- EXPECT_EQ(4, outBuffer_.getLength());
+ EXPECT_EQ(4, outBuf_.getLength());
uint8_t exp2[] = {125, 2, 12345/256, 12345%256};
- EXPECT_TRUE(0 == memcmp(exp2, outBuffer_.getData(), 4));
+ EXPECT_TRUE(0 == memcmp(exp2, outBuf_.getData(), 4));
// verity getUint32
- outBuffer_.clear();
+ outBuf_.clear();
opt4->setUint32(0x12345678);
- opt4->pack4(outBuffer_);
+ opt4->pack4(outBuf_);
EXPECT_EQ(0x12345678, opt4->getUint32());
EXPECT_EQ(6, opt4->len());
- EXPECT_EQ(6, outBuffer_.getLength());
+ EXPECT_EQ(6, outBuf_.getLength());
uint8_t exp4[] = {125, 4, 0x12, 0x34, 0x56, 0x78};
- EXPECT_TRUE(0 == memcmp(exp4, outBuffer_.getData(), 6));
+ EXPECT_TRUE(0 == memcmp(exp4, outBuf_.getData(), 6));
+}
}
diff --git a/src/lib/dhcp/tests/pkt6_unittest.cc b/src/lib/dhcp/tests/pkt6_unittest.cc
index 968b24c..75376cc 100644
--- a/src/lib/dhcp/tests/pkt6_unittest.cc
+++ b/src/lib/dhcp/tests/pkt6_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// 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
@@ -37,9 +37,11 @@ public:
};
TEST_F(Pkt6Test, constructor) {
- Pkt6 * pkt1 = new Pkt6(17);
+ uint8_t data[] = { 0, 1, 2, 3, 4, 5 };
+ Pkt6 * pkt1 = new Pkt6(data, sizeof(data) );
- EXPECT_EQ(pkt1->data_len_, 17);
+ EXPECT_EQ(6, pkt1->getData().size());
+ EXPECT_EQ(0, memcmp( &pkt1->getData()[0], data, sizeof(data)) );
delete pkt1;
}
@@ -49,42 +51,46 @@ TEST_F(Pkt6Test, constructor) {
// this code is autogenerated (see src/bin/dhcp6/tests/iface_mgr_unittest.c)
Pkt6 *capture1() {
Pkt6* pkt;
- pkt = new Pkt6(98);
- pkt->remote_port_ = 546;
- pkt->remote_addr_ = IOAddress("fe80::21e:8cff:fe9b:7349");
- pkt->local_port_ = 0;
- pkt->local_addr_ = IOAddress("ff02::1:2");
- pkt->ifindex_ = 2;
- pkt->iface_ = "eth0";
- pkt->data_[0]=1;
- pkt->data_[1]=01; pkt->data_[2]=02; pkt->data_[3]=03; pkt->data_[4]=0;
- pkt->data_[5]=1; pkt->data_[6]=0; pkt->data_[7]=14; pkt->data_[8]=0;
- pkt->data_[9]=1; pkt->data_[10]=0; pkt->data_[11]=1; pkt->data_[12]=21;
- pkt->data_[13]=158; pkt->data_[14]=60; pkt->data_[15]=22; pkt->data_[16]=0;
- pkt->data_[17]=30; pkt->data_[18]=140; pkt->data_[19]=155; pkt->data_[20]=115;
- pkt->data_[21]=73; pkt->data_[22]=0; pkt->data_[23]=3; pkt->data_[24]=0;
- pkt->data_[25]=40; pkt->data_[26]=0; pkt->data_[27]=0; pkt->data_[28]=0;
- pkt->data_[29]=1; pkt->data_[30]=255; pkt->data_[31]=255; pkt->data_[32]=255;
- pkt->data_[33]=255; pkt->data_[34]=255; pkt->data_[35]=255; pkt->data_[36]=255;
- pkt->data_[37]=255; pkt->data_[38]=0; pkt->data_[39]=5; pkt->data_[40]=0;
- pkt->data_[41]=24; pkt->data_[42]=32; pkt->data_[43]=1; pkt->data_[44]=13;
- pkt->data_[45]=184; pkt->data_[46]=0; pkt->data_[47]=1; pkt->data_[48]=0;
- pkt->data_[49]=0; pkt->data_[50]=0; pkt->data_[51]=0; pkt->data_[52]=0;
- pkt->data_[53]=0; pkt->data_[54]=0; pkt->data_[55]=0; pkt->data_[56]=18;
- pkt->data_[57]=52; pkt->data_[58]=255; pkt->data_[59]=255; pkt->data_[60]=255;
- pkt->data_[61]=255; pkt->data_[62]=255; pkt->data_[63]=255; pkt->data_[64]=255;
- pkt->data_[65]=255; pkt->data_[66]=0; pkt->data_[67]=23; pkt->data_[68]=0;
- pkt->data_[69]=16; pkt->data_[70]=32; pkt->data_[71]=1; pkt->data_[72]=13;
- pkt->data_[73]=184; pkt->data_[74]=0; pkt->data_[75]=1; pkt->data_[76]=0;
- pkt->data_[77]=0; pkt->data_[78]=0; pkt->data_[79]=0; pkt->data_[80]=0;
- pkt->data_[81]=0; pkt->data_[82]=0; pkt->data_[83]=0; pkt->data_[84]=221;
- pkt->data_[85]=221; pkt->data_[86]=0; pkt->data_[87]=8; pkt->data_[88]=0;
- pkt->data_[89]=2; pkt->data_[90]=0; pkt->data_[91]=100; pkt->data_[92]=0;
- pkt->data_[93]=6; pkt->data_[94]=0; pkt->data_[95]=2; pkt->data_[96]=0;
- pkt->data_[97]=23;
+ 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();
@@ -108,17 +114,12 @@ TEST_F(Pkt6Test, unpack_solicit1) {
EXPECT_FALSE(sol->getOption(D6O_IA_TA));
EXPECT_FALSE(sol->getOption(D6O_IAADDR));
- // let's limit verbosity of this test
- // std::cout << sol->toText();
-
delete sol;
}
TEST_F(Pkt6Test, packUnpack) {
- Pkt6 * parent = new Pkt6(100);
-
- parent->setType(DHCPV6_SOLICIT);
+ 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));
@@ -130,43 +131,37 @@ TEST_F(Pkt6Test, packUnpack) {
parent->addOption(opt3);
EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
- int transid = parent->getTransid();
- // transaction-id was randomized, let's remember it
// calculated length should be 16
- EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
+ 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,
+ EXPECT_EQ( Pkt6::DHCPV6_PKT_HDR_LEN + 3*Option::OPTION6_HDR_LEN,
parent->len() );
- // let's delete options from options_ collection
- // they still be defined in packed
- parent->options_.clear();
-
- // that that removed options are indeed are gone
- EXPECT_EQ( 4, 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( parent->unpack() );
+ EXPECT_TRUE( clone->unpack() );
// transid, message-type should be the same as before
- EXPECT_EQ(transid, parent->getTransid());
- EXPECT_EQ(DHCPV6_SOLICIT, parent->getType());
-
- EXPECT_TRUE( parent->getOption(1));
- EXPECT_TRUE( parent->getOption(2));
- EXPECT_TRUE( parent->getOption(100));
- EXPECT_FALSE( parent->getOption(4));
-
+ 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(100);
+ 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));
@@ -203,5 +198,4 @@ TEST_F(Pkt6Test, addGetDelOptions) {
delete parent;
}
-
}
diff --git a/src/lib/util/buffer.h b/src/lib/util/buffer.h
index eb90d64..24f2707 100644
--- a/src/lib/util/buffer.h
+++ b/src/lib/util/buffer.h
@@ -101,6 +101,17 @@ public:
/// \param len The length of the data in bytes.
InputBuffer(const void* data, size_t len) :
position_(0), data_(static_cast<const uint8_t*>(data)), len_(len) {}
+
+ /// @brief Constructor from vector<uint8_t>
+ ///
+ /// It is caller's responsibility to ensure that the data is valid as long
+ /// as the buffer exists.
+ ///
+ /// @param begin iterator to beginning of the vector
+ /// @param end iterator to end of the vector
+ InputBuffer(std::vector<uint8_t>::const_iterator begin,
+ std::vector<uint8_t>::const_iterator end) :
+ data_(&(*begin)), len_(distance(begin, end)) {}
//@}
///
More information about the bind10-changes
mailing list