BIND 10 trac1186, updated. ef2bbbcda5ae15f8b341c5ab299851688d84b59a [1186] Yet another set of changes after review.

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Oct 14 12:14:24 UTC 2011


The branch, trac1186 has been updated
       via  ef2bbbcda5ae15f8b341c5ab299851688d84b59a (commit)
       via  40249e03304a26d147f83fe1899a7fc8207c70f0 (commit)
       via  a7605f27d5575c6fbeb325705220039936c81e53 (commit)
       via  cb59e65da8d1c9498d1dc8845e277567814fe400 (commit)
       via  d8d0a731ce43167d98b7c7e855b8a31b9deacdfb (commit)
      from  516fca538ba6307d90cc3ac197871de91e092955 (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 ef2bbbcda5ae15f8b341c5ab299851688d84b59a
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Fri Oct 14 14:13:32 2011 +0200

    [1186] Yet another set of changes after review.
    
     - implementation for setProto() added
     - EXPECT_NO_THROW around many object creations added

commit 40249e03304a26d147f83fe1899a7fc8207c70f0
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Fri Oct 14 13:52:03 2011 +0200

    [1186] Changes after second review
    
    - added passing by reference in many places
    - started using writeUint16/readUint16 functions

commit a7605f27d5575c6fbeb325705220039936c81e53
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Fri Oct 14 12:07:23 2011 +0200

    [1186] doxygen comments cleanup.

commit cb59e65da8d1c9498d1dc8845e277567814fe400
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Fri Oct 14 12:00:02 2011 +0200

    [1186] control_buf_ is now scoped_array<char> in dhcp/iface_mgr

commit d8d0a731ce43167d98b7c7e855b8a31b9deacdfb
Author: Tomek Mrugalski <tomasz at isc.org>
Date:   Fri Oct 14 11:53:59 2011 +0200

    [1186] Changes in reply to review comment 13.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                      |   11 +
 src/bin/dhcp6/dhcp6_srv.h                      |  265 ++++++++---------
 src/bin/dhcp6/iface_mgr.cc                     |   63 +---
 src/bin/dhcp6/iface_mgr.h                      |  373 ++++++++++++-----------
 src/lib/dhcp/libdhcp.cc                        |    6 +-
 src/lib/dhcp/option.cc                         |   32 ++-
 src/lib/dhcp/option.h                          |   24 +-
 src/lib/dhcp/option6_addrlst.cc                |   28 +-
 src/lib/dhcp/option6_addrlst.h                 |    4 +-
 src/lib/dhcp/option6_ia.cc                     |   34 ++-
 src/lib/dhcp/option6_ia.h                      |    9 +-
 src/lib/dhcp/option6_iaaddr.cc                 |    6 +-
 src/lib/dhcp/option6_iaaddr.h                  |    4 +-
 src/lib/dhcp/pkt6.cc                           |    1 -
 src/lib/dhcp/pkt6.h                            |    2 +-
 src/lib/dhcp/tests/option6_addrlst_unittest.cc |   94 ++++---
 16 files changed, 486 insertions(+), 470 deletions(-)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 547192e..a9aad1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+294.    [func]*         tomek
+	libdhcp: DHCP packet library was implemented. Currently it handles
+	packet reception, option parsing, option generation and output
+	packet building. Generic and specialized classes for several
+	DHCPv6 options (IA_NA, IAADDR, address-list) are available. A
+	simple code was added that leverages libdhcp. It is a skeleton
+	DHCPv6 server. It receives incoming SOLICIT and REQUEST messages
+	and responds with proper ADVERTISE and REPLY. Note that since
+	LeaseManager is not implemented, server assigns a the same
+	hardcoded lease for every client.
+
 293.    [func]*		tomek
 	b10-dhcp6: Implemented DHCPv6 echo server. It joins DHCPv6
 	multicast groups and listens to incoming DHCPv6 client messages.
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index 90ecb8a..4daef3a 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -23,143 +23,134 @@
 
 namespace isc {
 
-    namespace dhcp {
-    /// @brief DHCPv6 server service.
-    ///
-    /// This singleton class represents DHCPv6 server. It contains all
-    /// top-level methods and routines necessary for server operation.
-    /// In particular, it instantiates IfaceMgr, loads or generates DUID
-    /// that is going to be used as server-identifier, receives incoming
-    /// packets, processes them, manages leases assignment and generates
-    /// appropriate responses.
-    class Dhcpv6Srv : public boost::noncopyable {
-        private:
-
-        /// @brief A private copy constructor.
-        ///
-        /// Creates a single Dhcpv6Srv instance and all required objects,
-        /// including interface manager (IfaceMgr). It is defined private on
-        /// purpose. We don't want to have more than one copy of Dhcpv6Srv.
-        ///
-        /// It may throw exceptions if server creation failed, e.g. due to
-        /// failures in IfaceMgr (e.g. socket creation) or unavailable
-        /// interfaces when attempting to create new DUID.
-        Dhcpv6Srv(const Dhcpv6Srv& src);
-
-        /// @brief A private assignment operator.
-        ///
-        /// Note that there is no implementation of this assignment operator.
-        /// Its definition is here to prevent creation of any copies.
-        ///
-        Dhcpv6Srv& operator=(const Dhcpv6Srv& src);
-
-        /// @brief Sets server-identifier.
-        ///
-        /// This method attempts to set server-identifier DUID. It loads it
-        /// from a file. If file load fails, it generates new DUID using
-        /// interface link-layer addresses (EUI-64) + timestamp (DUID type
-        /// duid-llt, see RFC3315, section 9.2). If there are no suitable
-        /// interfaces present, exception it thrown
-        ///
-        /// @throws isc::Unexpected Failed to read DUID file and no suitable
-        ///         interfaces for new DUID generation are detected.
-        void setServerID();
-
-        /// server DUID (to be sent in server-identifier option)
-        boost::shared_ptr<isc::dhcp::Option> serverid_;
-
-    public:
-        /// @brief Default constructor.
-        ///
-        /// Instantiates necessary services, required to run DHCPv6 server.
-        /// In particular, creates IfaceMgr that will be responsible for
-        /// network interaction. Will instantiate lease manager, and load
-        /// old or create new DUID.
-        Dhcpv6Srv();
-
-        /// @brief Destructor. Shuts down DHCPv6 service.
-        ~Dhcpv6Srv();
-
-        /// @brief Returns server-intentifier option
-        ///
-        /// @return reference to server-id option
-        ///
-        boost::shared_ptr<isc::dhcp::Option>&
-        getServerID() { return serverid_; }
-
-        /// @brief Main server processing loop.
-        ///
-        /// Main server processing loop. Receives incoming packets, verifies
-        /// their correctness, generates appropriate answer (if needed) and
-        /// transmits respones.
-        ///
-        /// @return true, if being shut down gracefully, fail if experienced
-        ///         critical error.
-        bool run();
-
-    protected:
-        /// @brief Processes incoming SOLICIT and returns response.
-        ///
-        /// Processes received SOLICIT message and verifies that its sender
-        /// should be served. In particular IA, TA and PD options are populated
-        /// with to-be assinged addresses, temporary addresses and delegated
-        /// prefixes, respectively. In the usual 4 message exchange, server is
-        /// expected to respond with ADVERTISE message. However, if client
-        /// requests rapid-commit and server supports it, REPLY will be sent
-        /// instead of ADVERTISE and requested leases will be assigned
-        /// immediately.
-        ///
-        /// @param solicit SOLICIT message received from client
-        ///
-        /// @return ADVERTISE, REPLY message or NULL
-        ///
-        boost::shared_ptr<Pkt6>
-        processSolicit(boost::shared_ptr<Pkt6> solicit);
-
-        /// @brief Processes incoming REQUEST and returns REPLY response.
-        ///
-        /// Processes incoming REQUEST message and verifies that its sender
-        /// should be served. In particular IA, TA and PD options are populated
-        /// with assinged addresses, temporary addresses and delegated
-        /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
-        /// leases.
-        ///
-        /// @param request REQUEST message received from client
-        ///
-        /// @return REPLY message or NULL
-        boost::shared_ptr<Pkt6>
-        processRequest(boost::shared_ptr<Pkt6> request);
-
-        /// @brief Stub function that will handle incoming RENEW messages.
-        boost::shared_ptr<Pkt6>
-        processRenew(boost::shared_ptr<Pkt6> renew);
-
-         /// @brief Stub function that will handle incoming REBIND messages.
-        boost::shared_ptr<Pkt6>
-        processRebind(boost::shared_ptr<Pkt6> rebind);
-
-        /// @brief Stub function that will handle incoming CONFIRM messages.
-        boost::shared_ptr<Pkt6>
-        processConfirm(boost::shared_ptr<Pkt6> confirm);
-
-        /// @brief Stub function that will handle incoming RELEASE messages.
-        boost::shared_ptr<Pkt6>
-        processRelease(boost::shared_ptr<Pkt6> release);
-
-        /// @brief Stub function that will handle incoming DECLINE messages.
-        boost::shared_ptr<Pkt6>
-        processDecline(boost::shared_ptr<Pkt6> decline);
-
-        /// @brief Stub function that will handle incoming INF-REQUEST messages.
-        boost::shared_ptr<Pkt6>
-        processInfRequest(boost::shared_ptr<Pkt6> infRequest);
-
-        /// indicates if shutdown is in progress. Setting it to true will
-        /// initiate server shutdown procedure.
-        volatile bool shutdown;
-    };
-
-    }; // namespace isc::dhcp
+namespace dhcp {
+/// @brief DHCPv6 server service.
+///
+/// This singleton class represents DHCPv6 server. It contains all
+/// top-level methods and routines necessary for server operation.
+/// In particular, it instantiates IfaceMgr, loads or generates DUID
+/// that is going to be used as server-identifier, receives incoming
+/// packets, processes them, manages leases assignment and generates
+/// appropriate responses.
+class Dhcpv6Srv : public boost::noncopyable {
+
+public:
+    /// @brief Default constructor.
+    ///
+    /// Instantiates necessary services, required to run DHCPv6 server.
+    /// In particular, creates IfaceMgr that will be responsible for
+    /// network interaction. Will instantiate lease manager, and load
+    /// old or create new DUID.
+    Dhcpv6Srv();
+
+    /// @brief Destructor. Used during DHCPv6 service shutdown.
+    ~Dhcpv6Srv();
+
+    /// @brief Returns server-intentifier option
+    ///
+    /// @return server-id option
+    boost::shared_ptr<isc::dhcp::Option>
+    getServerID() { return serverid_; }
+
+    /// @brief Main server processing loop.
+    ///
+    /// Main server processing loop. Receives incoming packets, verifies
+    /// their correctness, generates appropriate answer (if needed) and
+    /// transmits respones.
+    ///
+    /// @return true, if being shut down gracefully, fail if experienced
+    ///         critical error.
+    bool run();
+
+protected:
+    /// @brief Processes incoming SOLICIT and returns response.
+    ///
+    /// Processes received SOLICIT message and verifies that its sender
+    /// should be served. In particular IA, TA and PD options are populated
+    /// with to-be assinged addresses, temporary addresses and delegated
+    /// prefixes, respectively. In the usual 4 message exchange, server is
+    /// expected to respond with ADVERTISE message. However, if client
+    /// requests rapid-commit and server supports it, REPLY will be sent
+    /// instead of ADVERTISE and requested leases will be assigned
+    /// immediately.
+    ///
+    /// @param solicit SOLICIT message received from client
+    ///
+    /// @return ADVERTISE, REPLY message or NULL
+    boost::shared_ptr<Pkt6>
+    processSolicit(boost::shared_ptr<Pkt6> solicit);
+
+    /// @brief Processes incoming REQUEST and returns REPLY response.
+    ///
+    /// Processes incoming REQUEST message and verifies that its sender
+    /// should be served. In particular IA, TA and PD options are populated
+    /// with assinged addresses, temporary addresses and delegated
+    /// prefixes, respectively. Uses LeaseMgr to allocate or update existing
+    /// leases.
+    ///
+    /// @param request a message received from client
+    ///
+    /// @return REPLY message or NULL
+    boost::shared_ptr<Pkt6>
+    processRequest(boost::shared_ptr<Pkt6> request);
+
+    /// @brief Stub function that will handle incoming RENEW messages.
+    ///
+    /// @param renew message received from client
+    boost::shared_ptr<Pkt6>
+    processRenew(boost::shared_ptr<Pkt6> renew);
+
+    /// @brief Stub function that will handle incoming REBIND messages.
+    ///
+    /// @param rebind message received from client
+    boost::shared_ptr<Pkt6>
+    processRebind(boost::shared_ptr<Pkt6> rebind);
+
+    /// @brief Stub function that will handle incoming CONFIRM messages.
+    ///
+    /// @param confirm message received from client
+    boost::shared_ptr<Pkt6>
+    processConfirm(boost::shared_ptr<Pkt6> confirm);
+
+    /// @brief Stub function that will handle incoming RELEASE messages.
+    ///
+    /// @param release message received from client
+    boost::shared_ptr<Pkt6>
+    processRelease(boost::shared_ptr<Pkt6> release);
+
+    /// @brief Stub function that will handle incoming DECLINE messages.
+    ///
+    /// @param decline message received from client
+    boost::shared_ptr<Pkt6>
+    processDecline(boost::shared_ptr<Pkt6> decline);
+
+    /// @brief Stub function that will handle incoming INF-REQUEST messages.
+    ///
+    /// @param infRequest message received from client
+    boost::shared_ptr<Pkt6>
+    processInfRequest(boost::shared_ptr<Pkt6> infRequest);
+
+    /// @brief Sets server-identifier.
+    ///
+    /// This method attempts to set server-identifier DUID. It loads it
+    /// from a file. If file load fails, it generates new DUID using
+    /// interface link-layer addresses (EUI-64) + timestamp (DUID type
+    /// duid-llt, see RFC3315, section 9.2). If there are no suitable
+    /// interfaces present, exception it thrown
+    ///
+    /// @throws isc::Unexpected Failed to read DUID file and no suitable
+    ///         interfaces for new DUID generation are detected.
+    void setServerID();
+
+    /// server DUID (to be sent in server-identifier option)
+    boost::shared_ptr<isc::dhcp::Option> serverid_;
+
+    /// indicates if shutdown is in progress. Setting it to true will
+    /// initiate server shutdown procedure.
+    volatile bool shutdown;
+};
+
+}; // namespace isc::dhcp
 }; // namespace isc
 
 #endif // DHCP6_SRV_H
diff --git a/src/bin/dhcp6/iface_mgr.cc b/src/bin/dhcp6/iface_mgr.cc
index cf1cb48..7513cd5 100644
--- a/src/bin/dhcp6/iface_mgr.cc
+++ b/src/bin/dhcp6/iface_mgr.cc
@@ -30,14 +30,14 @@ using namespace isc::dhcp;
 
 namespace isc {
 
-// IfaceMgr is a singleton implementation
+/// IfaceMgr is a singleton implementation
 IfaceMgr* IfaceMgr::instance_ = 0;
 
 void
 IfaceMgr::instanceCreate() {
     if (instance_) {
         // no need to do anything. Instance is already created.
-        // Who called it again anyway? Uh oh. Had to be us, as 
+        // Who called it again anyway? Uh oh. Had to be us, as
         // this is private method.
         return;
     }
@@ -70,17 +70,20 @@ IfaceMgr::Iface::getPlainMac() const {
     ostringstream tmp;
     tmp.fill('0');
     tmp << hex;
-    for (int i=0; i<mac_len_; i++) {
+    for (int i = 0; i < mac_len_; i++) {
         tmp.width(2);
         tmp << mac_[i];
-        if (i<mac_len_-1) {
+        if (i < mac_len_-1) {
             tmp << ":";
         }
     }
     return (tmp.str());
 }
 
-IfaceMgr::IfaceMgr() {
+IfaceMgr::IfaceMgr()
+    :control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
+     control_buf_(new char[control_buf_len_])
+{
 
     cout << "IfaceMgr initialization." << endl;
 
@@ -88,8 +91,8 @@ IfaceMgr::IfaceMgr() {
         // required for sending/receiving packets
         // let's keep it in front, just in case someone
         // wants to send anything during initialization
-        control_buf_len_ = CMSG_SPACE(sizeof(struct in6_pktinfo));
-        control_buf_ = new char[control_buf_len_];
+
+        // control_buf_ = boost::scoped_array<char>();
 
         detectIfaces();
 
@@ -108,11 +111,7 @@ IfaceMgr::IfaceMgr() {
 }
 
 IfaceMgr::~IfaceMgr() {
-    if (control_buf_) {
-        delete [] control_buf_;
-        control_buf_ = 0;
-        control_buf_len_ = 0;
-    }
+    // control_buf_ is deleted automatically (scoped_ptr)
     control_buf_len_ = 0;
 }
 
@@ -321,15 +320,6 @@ IfaceMgr::openSocket(const std::string& ifname,
     return (sock);
 }
 
-/**
- * joins multicast group
- *
- * @param sock socket file descriptor
- * @param ifname name of the interface (DHCPv6 uses link-scoped mc groups)
- * @param mcast multicast address to join (string)
- *
- * @return true if joined successfully, false otherwise
- */
 bool
 IfaceMgr::joinMcast(int sock, const std::string& ifname,
 const std::string & mcast) {
@@ -355,25 +345,14 @@ const std::string & mcast) {
     return (true);
 }
 
-/**
- * Sends UDP packet over IPv6.
- *
- * All parameters for actual transmission are specified in
- * Pkt6 structure itself. That includes destination address,
- * src/dst port and interface over which data will be sent.
- *
- * @param pkt A packet object that is going to be sent.
- *
- * @return True, if transmission was successful. False otherwise.
- */
 bool
-IfaceMgr::send(boost::shared_ptr<Pkt6> pkt) {
+IfaceMgr::send(boost::shared_ptr<Pkt6>& pkt) {
     struct msghdr m;
     struct iovec v;
     int result;
     struct in6_pktinfo *pktinfo;
     struct cmsghdr *cmsg;
-    memset(control_buf_, 0, control_buf_len_);
+    memset(&control_buf_[0], 0, control_buf_len_);
 
     /*
      * Initialize our message header structure.
@@ -413,7 +392,7 @@ IfaceMgr::send(boost::shared_ptr<Pkt6> pkt) {
      * source address if we wanted, but we can safely let the
      * kernel decide what that should be.
      */
-    m.msg_control = control_buf_;
+    m.msg_control = &control_buf_[0];
     m.msg_controllen = control_buf_len_;
     cmsg = CMSG_FIRSTHDR(&m);
     cmsg->cmsg_level = IPPROTO_IPV6;
@@ -439,16 +418,6 @@ IfaceMgr::send(boost::shared_ptr<Pkt6> pkt) {
     return (result);
 }
 
-
-/**
- * Attempts to receive UDP/IPv6 packet over open sockets.
- *
- * TODO Start using select() and add timeout to be able
- * to not wait infinitely, but rather do something useful
- * (e.g. remove expired leases)
- *
- * @return Object prepresenting received packet.
- */
 boost::shared_ptr<Pkt6>
 IfaceMgr::receive() {
     struct msghdr m;
@@ -475,7 +444,7 @@ IfaceMgr::receive() {
         return (boost::shared_ptr<Pkt6>()); // NULL
     }
 
-    memset(control_buf_, 0, control_buf_len_);
+    memset(&control_buf_[0], 0, control_buf_len_);
 
     memset(&from, 0, sizeof(from));
     memset(&to_addr, 0, sizeof(to_addr));
@@ -509,7 +478,7 @@ IfaceMgr::receive() {
      * information (when we initialized the interface), so we
      * should get the destination address from that.
      */
-    m.msg_control = control_buf_;
+    m.msg_control = &control_buf_[0];
     m.msg_controllen = control_buf_len_;
 
     result = recvmsg(recvsock_, &m, 0);
diff --git a/src/bin/dhcp6/iface_mgr.h b/src/bin/dhcp6/iface_mgr.h
index cc89045..249c7ef 100644
--- a/src/bin/dhcp6/iface_mgr.h
+++ b/src/bin/dhcp6/iface_mgr.h
@@ -17,196 +17,213 @@
 
 #include <list>
 #include <boost/shared_ptr.hpp>
+#include <boost/scoped_array.hpp>
 #include <boost/noncopyable.hpp>
 #include "asiolink/io_address.h"
 #include "dhcp/pkt6.h"
 
 namespace isc {
 
-    namespace dhcp {
-    /// @brief handles network interfaces, transmission and reception
+namespace dhcp {
+/// @brief handles network interfaces, transmission and reception
+///
+/// IfaceMgr is an interface manager class that detects available network
+/// interfaces, configured addresses, link-local addresses, and provides
+/// API for using sockets.
+///
+class IfaceMgr : public boost::noncopyable {
+public:
+    /// type that defines list of addresses
+    typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
+
+    /// maximum MAC address length (Infiniband uses 20 bytes)
+    static const unsigned int MAX_MAC_LEN = 20;
+
+    /// @brief represents a single network interface
     ///
-    /// IfaceMgr is an interface manager class that detects available network
-    /// interfaces, configured addresses, link-local addresses, and provides
-    /// API for using sockets.
-    ///
-    class IfaceMgr : public boost::noncopyable {
-    public:
-        /// type that defines list of addresses
-        typedef std::list<isc::asiolink::IOAddress> Addr6Lst;
+    /// Iface structure represents network interface with all useful
+    /// information, like name, interface index, MAC address and
+    /// list of assigned addresses
+    struct Iface {
+        /// constructor
+        Iface(const std::string& name, int ifindex);
+
+        /// returns full interface name in format ifname/ifindex
+        std::string getFullName() const;
+
+        /// returns link-layer address a plain text
+        std::string getPlainMac() const;
 
-        /// maximum MAC address length (Infiniband uses 20 bytes)
-        static const unsigned int MAX_MAC_LEN = 20;
+        /// network interface name
+        std::string name_;
+
+        /// interface index (a value that uniquely indentifies an interface)
+        int ifindex_;
 
-        /// @brief represents a single network interface
-        ///
-        /// Iface structure represents network interface with all useful
-        /// information, like name, interface index, MAC address and
         /// list of assigned addresses
-        struct Iface {
-            /// constructor
-            Iface(const std::string& name, int ifindex);
-
-            /// returns full interface name in format ifname/ifindex
-            std::string getFullName() const;
-
-            /// returns link-layer address a plain text
-            std::string getPlainMac() const;
-
-            std::string name_; /// network interface name
-            int ifindex_;      /// interface index (a value that uniquely
-                               /// indentifies an interface
-            Addr6Lst addrs_;   /// list of assigned addresses
-            uint8_t mac_[MAX_MAC_LEN]; /// link-layer address
-            int mac_len_;      /// length of link-layer address (usually 6)
-
-            int sendsock_; /// socket used to sending data
-            int recvsock_; /// socket used for receiving data
-
-            // next field is not needed, let's keep it in cointainers
-        };
-
-        // TODO performance improvement: we may change this into
-        //      2 maps (ifindex-indexed and name-indexed) and
-        //      also hide it (make it public make tests easier for now)
-        typedef std::list<Iface> IfaceLst;
-
-        /// IfaceMgr is a singleton class. This method returns reference
-        /// to its sole instance.
-        ///
-        /// @return the only existing instance of interface manager
-        static IfaceMgr& instance();
-
-        /// @brief Returns interface with specified interface index
-        ///
-        /// @param ifindex index of searched interface
-        ///
-        /// @return interface with requested index (or NULL if no such
-        ///         interface is present)
-        ///
-        Iface*
-        getIface(int ifindex);
-
-        /// @brief Returns interface with specified interface name
-        ///
-        /// @param ifname name of searched interface
-        ///
-        /// @return interface with requested name (or NULL if no such
-        ///         interface is present)
-        ///
-        Iface*
-        getIface(const std::string& ifname);
-
-        /// debugging method that prints out all available interfaces
-        ///
-        /// @param out specifies stream to print list of interfaces to
-        void
-        printIfaces(std::ostream& out = std::cout);
-
-        /// @brief Sends a packet.
-        ///
-        /// Sends a packet. All parameters regarding interface, destination
-        /// address are set in pkt object.
-        ///
-        /// @param pkt packet to be sent
-        ///
-        /// @return true if sending was successful
-        ///
-        bool
-        send(boost::shared_ptr<Pkt6> pkt);
-
-        /// @brief Tries to receive packet over open sockets.
-        ///
-        /// Attempts to receive a single packet of any of the open sockets.
-        /// If reception is successful and all information about its sender
-        /// are obtained, Pkt6 object is created and returned.
-        ///
-        /// @return Pkt6 object representing received packet (or NULL)
-        ///
-        boost::shared_ptr<Pkt6> receive();
-
-        // don't use private, we need derived classes in tests
-    protected:
-
-        /// @brief Protected constructor.
-        ///
-        /// Protected constructor. This is a singleton class. We don't want
-        /// anyone to create instances of IfaceMgr. Use instance() method
-        IfaceMgr();
-
-        ~IfaceMgr();
-
-        /// @brief Detects network interfaces.
-        ///
-        /// This method will eventually detect available interfaces. For now
-        /// it offers stub implementation. First interface name and link-local
-        /// IPv6 address is read from intefaces.txt file.
-        void
-        detectIfaces();
-
-        ///
-        /// Opens UDP/IPv6 socket and binds it to address, interface nad port.
-        ///
-        /// @param ifname name of the interface
-        /// @param addr address to be bound.
-        /// @param port UDP port.
-        ///
-        /// @return socket descriptor, if socket creation, binding and multicast
-        /// group join were all successful. -1 otherwise.
-        int openSocket(const std::string& ifname,
-                       const isc::asiolink::IOAddress& addr,
-                       int port);
-
-        // TODO: having 2 maps (ifindex->iface and ifname->iface would)
-        //      probably be better for performance reasons
-
-        /// List of available interfaces
-        IfaceLst ifaces_;
-
-        /// a pointer to a sole instance of this class (a singleton)
-        static IfaceMgr * instance_;
-
-        // TODO: Also keep this interface on Iface once interface detection
-        // is implemented. We may need it e.g. to close all sockets on
-        // specific interface
-        int recvsock_; // TODO: should be fd_set eventually, but we have only
-        int sendsock_; // 2 sockets for now. Will do for until next release
-        // we can't use the same socket, as receiving socket
-        // is bound to multicast address. And we all know what happens
-        // to people who try to use multicast as source address.
-
-        /// control-buffer, used in transmission and reception
-        char * control_buf_;
-        int control_buf_len_;
-
-    private:
-        /// Opens sockets on detected interfaces.
-        bool
-        openSockets();
-
-        /// creates a single instance of this class (a singleton implementation)
-        static void
-        instanceCreate();
-
-        /// @brief Joins IPv6 multicast group on a socket.
-        ///
-        /// Socket must be created and bound to an address. Note that this
-        /// address is different than the multicast address. For example DHCPv6
-        /// server should bind its socket to link-local address (fe80::1234...)
-        /// and later join ff02::1:2 multicast group.
-        ///
-        /// @param sock socket fd (socket must be bound)
-        /// @param ifname interface name (for link-scoped multicast groups)
-        /// @param mcast multicast address to join (e.g. "ff02::1:2")
-        ///
-        /// @return true if multicast join was successful
-        ///
-        bool
-        joinMcast(int sock, const std::string& ifname,
-                  const std::string& mcast);
+        Addr6Lst addrs_;
+
+        /// link-layer address
+        uint8_t mac_[MAX_MAC_LEN];
+
+        /// length of link-layer address (usually 6)
+        int mac_len_;
+
+        /// socket used to sending data
+        int sendsock_;
+
+        /// socket used for receiving data
+        int recvsock_;
     };
 
-    }; // namespace isc::dhcp
+    // TODO performance improvement: we may change this into
+    //      2 maps (ifindex-indexed and name-indexed) and
+    //      also hide it (make it public make tests easier for now)
+
+    /// type that holds a list of interfaces
+    typedef std::list<Iface> IfaceLst;
+
+    /// IfaceMgr is a singleton class. This method returns reference
+    /// to its sole instance.
+    ///
+    /// @return the only existing instance of interface manager
+    static IfaceMgr& instance();
+
+    /// @brief Returns interface with specified interface index
+    ///
+    /// @param ifindex index of searched interface
+    ///
+    /// @return interface with requested index (or NULL if no such
+    ///         interface is present)
+    ///
+    Iface*
+    getIface(int ifindex);
+
+    /// @brief Returns interface with specified interface name
+    ///
+    /// @param ifname name of searched interface
+    ///
+    /// @return interface with requested name (or NULL if no such
+    ///         interface is present)
+    ///
+    Iface*
+    getIface(const std::string& ifname);
+
+    /// debugging method that prints out all available interfaces
+    ///
+    /// @param out specifies stream to print list of interfaces to
+    void
+    printIfaces(std::ostream& out = std::cout);
+
+    /// @brief Sends a packet.
+    ///
+    /// Sends a packet. All parameters for actual transmission are specified in
+    /// Pkt6 structure itself. That includes destination address, src/dst port
+    /// and interface over which data will be sent.
+    ///
+    /// @param pkt packet to be sent
+    ///
+    /// @return true if sending was successful
+    bool
+    send(boost::shared_ptr<Pkt6>& pkt);
+
+    /// @brief Tries to receive packet over open sockets.
+    ///
+    /// Attempts to receive a single packet of any of the open sockets.
+    /// If reception is successful and all information about its sender
+    /// are obtained, Pkt6 object is created and returned.
+    ///
+    /// TODO Start using select() and add timeout to be able
+    /// to not wait infinitely, but rather do something useful
+    /// (e.g. remove expired leases)
+    ///
+    /// @return Pkt6 object representing received packet (or NULL)
+    boost::shared_ptr<Pkt6> receive();
+
+    // don't use private, we need derived classes in tests
+protected:
+
+    /// @brief Protected constructor.
+    ///
+    /// Protected constructor. This is a singleton class. We don't want
+    /// anyone to create instances of IfaceMgr. Use instance() method
+    IfaceMgr();
+
+    ~IfaceMgr();
+
+    /// @brief Detects network interfaces.
+    ///
+    /// This method will eventually detect available interfaces. For now
+    /// it offers stub implementation. First interface name and link-local
+    /// IPv6 address is read from intefaces.txt file.
+    void
+    detectIfaces();
+
+    ///
+    /// Opens UDP/IPv6 socket and binds it to address, interface and port.
+    ///
+    /// @param ifname name of the interface
+    /// @param addr address to be bound.
+    /// @param port UDP port.
+    ///
+    /// @return socket descriptor, if socket creation, binding and multicast
+    /// group join were all successful. -1 otherwise.
+    int openSocket(const std::string& ifname,
+                   const isc::asiolink::IOAddress& addr,
+                   int port);
+
+    // TODO: having 2 maps (ifindex->iface and ifname->iface would)
+    //      probably be better for performance reasons
+
+    /// List of available interfaces
+    IfaceLst ifaces_;
+
+    /// a pointer to a sole instance of this class (a singleton)
+    static IfaceMgr * instance_;
+
+    // TODO: Also keep this interface on Iface once interface detection
+    // is implemented. We may need it e.g. to close all sockets on
+    // specific interface
+    int recvsock_; // TODO: should be fd_set eventually, but we have only
+    int sendsock_; // 2 sockets for now. Will do for until next release
+    // we can't use the same socket, as receiving socket
+    // is bound to multicast address. And we all know what happens
+    // to people who try to use multicast as source address.
+
+    /// length of the control_buf_ array
+    int control_buf_len_;
+
+    /// control-buffer, used in transmission and reception
+    boost::scoped_array<char> control_buf_;
+
+private:
+    /// Opens sockets on detected interfaces.
+    bool
+    openSockets();
+
+    /// creates a single instance of this class (a singleton implementation)
+    static void
+    instanceCreate();
+
+    /// @brief Joins IPv6 multicast group on a socket.
+    ///
+    /// Socket must be created and bound to an address. Note that this
+    /// address is different than the multicast address. For example DHCPv6
+    /// server should bind its socket to link-local address (fe80::1234...)
+    /// and later join ff02::1:2 multicast group.
+    ///
+    /// @param sock socket fd (socket must be bound)
+    /// @param ifname interface name (for link-scoped multicast groups)
+    /// @param mcast multicast address to join (e.g. "ff02::1:2")
+    ///
+    /// @return true if multicast join was successful
+    ///
+    bool
+    joinMcast(int sock, const std::string& ifname,
+              const std::string& mcast);
+};
+
+}; // namespace isc::dhcp
 }; // namespace isc
 
 #endif
diff --git a/src/lib/dhcp/libdhcp.cc b/src/lib/dhcp/libdhcp.cc
index 15cccdd..55c4ee7 100644
--- a/src/lib/dhcp/libdhcp.cc
+++ b/src/lib/dhcp/libdhcp.cc
@@ -40,10 +40,10 @@ LibDHCP::unpackOptions6(const boost::shared_array<uint8_t> buf,
     }
     unsigned int end = offset + parse_len;
 
-    while ( offset +4 <= end ) {
-        unsigned int opt_type = buf[offset]*256 + buf[offset+1];
+    while (offset +4 <= end) {
+        uint16_t opt_type = buf[offset]*256 + buf[offset+1];
         offset += 2;
-        unsigned int opt_len = buf[offset]*256 + buf[offset+1];
+        uint16_t opt_len = buf[offset]*256 + buf[offset+1];
         offset += 2;
 
         if (offset + opt_len > end ) {
diff --git a/src/lib/dhcp/option.cc b/src/lib/dhcp/option.cc
index 6dafbbd..20eaf34 100644
--- a/src/lib/dhcp/option.cc
+++ b/src/lib/dhcp/option.cc
@@ -19,12 +19,14 @@
 #include <iomanip>
 #include <boost/shared_array.hpp>
 #include "exceptions/exceptions.h"
+#include "util/io_utilities.h"
 
-#include "option.h"
-#include "libdhcp.h"
+#include "dhcp/option.h"
+#include "dhcp/libdhcp.h"
 
 using namespace std;
 using namespace isc::dhcp;
+using namespace isc::util;
 
 Option::Option(Universe u, unsigned short type)
     :universe_(u), type_(type), data_len_(0) {
@@ -33,7 +35,7 @@ Option::Option(Universe u, unsigned short type)
 }
 
 Option::Option(Universe u, unsigned short type,
-               boost::shared_array<uint8_t> buf,
+               const boost::shared_array<uint8_t>& buf,
                unsigned int offset, unsigned int len)
     :universe_(u), type_(type), data_(buf),
      data_len_(len), offset_(offset)
@@ -44,7 +46,7 @@ Option::Option(Universe u, unsigned short type,
 }
 
 unsigned int
-Option::pack(boost::shared_array<uint8_t> buf,
+Option::pack(boost::shared_array<uint8_t>& buf,
              unsigned int buf_len,
              unsigned int offset) {
     switch (universe_) {
@@ -59,7 +61,7 @@ Option::pack(boost::shared_array<uint8_t> buf,
 
 
 unsigned int
-Option::pack4(boost::shared_array<uint8_t> buf,
+Option::pack4(boost::shared_array<uint8_t>& buf,
              unsigned int buf_len,
              unsigned int offset) {
     if ( offset+len() > buf_len ) {
@@ -76,7 +78,7 @@ Option::pack4(boost::shared_array<uint8_t> buf,
 }
 
 unsigned int
-Option::pack6(boost::shared_array<uint8_t> buf,
+Option::pack6(boost::shared_array<uint8_t>& buf,
              unsigned int buf_len,
              unsigned int offset) {
     if ( offset+len() > buf_len ) {
@@ -87,20 +89,22 @@ Option::pack6(boost::shared_array<uint8_t> buf,
     int length = len() - getHeaderLen();
 
     uint8_t * ptr = &buf[offset];
-    *(uint16_t*)ptr = htons(type_);
-    ptr += 2;
-    *(uint16_t*)ptr = htons(length);
-    ptr += 2;
+    writeUint16(type_, ptr);
+    ptr += sizeof(uint16_t);
+
+    writeUint16(length, ptr);
+    ptr += sizeof(uint16_t);
+
     if (data_len_)
         memcpy(ptr, &data_[offset_], data_len_);
 
-    offset += 4 + data_len_; // end of this option
+    offset += OPTION6_HDR_LEN + data_len_; // end of this option
 
     return LibDHCP::packOptions6(buf, buf_len, offset, options_);
 }
 
 unsigned int
-Option::unpack(boost::shared_array<uint8_t> buf,
+Option::unpack(const boost::shared_array<uint8_t>& buf,
                unsigned int buf_len,
                unsigned int offset,
                unsigned int parse_len) {
@@ -117,7 +121,7 @@ Option::unpack(boost::shared_array<uint8_t> buf,
 }
 
 unsigned int
-Option::unpack4(boost::shared_array<uint8_t>,
+Option::unpack4(const boost::shared_array<uint8_t>&,
                 unsigned int ,
                 unsigned int ,
                 unsigned int ) {
@@ -126,7 +130,7 @@ Option::unpack4(boost::shared_array<uint8_t>,
 }
 
 unsigned int
-Option::unpack6(boost::shared_array<uint8_t> buf,
+Option::unpack6(const boost::shared_array<uint8_t>& buf,
                 unsigned int buf_len,
                 unsigned int offset,
                 unsigned int parse_len) {
diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h
index db5de84..f81a065 100644
--- a/src/lib/dhcp/option.h
+++ b/src/lib/dhcp/option.h
@@ -52,7 +52,7 @@ public:
     /// @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,
+                                              boost::shared_array<uint8_t>& buf,
                                               unsigned int offset,
                                               unsigned int len);
 
@@ -75,8 +75,8 @@ public:
     /// @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, boost::shared_array<uint8_t> buf,
-           unsigned int offset,
+    Option(Universe u, unsigned short type,
+           const boost::shared_array<uint8_t>& buf, unsigned int offset,
            unsigned int len);
 
     /// @brief writes option in wire-format to buf
@@ -92,7 +92,7 @@ public:
     /// @return offset to first unused byte after stored option
     ///
     virtual unsigned int
-    pack(boost::shared_array<uint8_t> buf,
+    pack(boost::shared_array<uint8_t>& buf,
          unsigned int buf_len,
          unsigned int offset);
 
@@ -108,7 +108,7 @@ public:
     ///
     /// @return offset after last parsed octet
     virtual unsigned int
-    unpack(boost::shared_array<uint8_t> buf,
+    unpack(const boost::shared_array<uint8_t>& buf,
            unsigned int buf_len,
            unsigned int offset,
            unsigned int parse_len);
@@ -157,6 +157,12 @@ public:
     /// Some DHCPv6 options can have suboptions. This method allows adding
     /// options within options.
     ///
+    /// Note: option is passed by value. That is very convenient as it allows
+    /// downcasting from any derived classes, e.g. shared_ptr<Option6_IA> type
+    /// can be passed directly, without any casts. That would not be possible
+    /// with passing by reference. addOption() is expected to be used in
+    /// 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);
@@ -192,7 +198,7 @@ protected:
     ///
     /// @return offset to the next byte after last used byte
     virtual unsigned int
-    pack4(boost::shared_array<uint8_t> buf,
+    pack4(boost::shared_array<uint8_t>& buf,
           unsigned int buf_len,
           unsigned int offset);
 
@@ -205,7 +211,7 @@ protected:
     ///
     /// @return offset to the next byte after last used byte
     virtual unsigned int
-    pack6(boost::shared_array<uint8_t> buf,
+    pack6(boost::shared_array<uint8_t>& buf,
           unsigned int buf_len,
           unsigned int offset);
 
@@ -217,7 +223,7 @@ protected:
     ///
     /// @return offset to the next byte after last parsed byte
     virtual unsigned int
-    unpack4(boost::shared_array<uint8_t> buf,
+    unpack4(const boost::shared_array<uint8_t>& buf,
             unsigned int buf_len,
             unsigned int offset,
             unsigned int parse_len);
@@ -230,7 +236,7 @@ protected:
     ///
     /// @return offset to the next byte after last parsed byte
     virtual unsigned int
-    unpack6(boost::shared_array<uint8_t> buf,
+    unpack6(const boost::shared_array<uint8_t>& buf,
             unsigned int buf_len,
             unsigned int offset,
             unsigned int parse_len);
diff --git a/src/lib/dhcp/option6_addrlst.cc b/src/lib/dhcp/option6_addrlst.cc
index 60263c2..fc981fa 100644
--- a/src/lib/dhcp/option6_addrlst.cc
+++ b/src/lib/dhcp/option6_addrlst.cc
@@ -18,6 +18,7 @@
 #include "exceptions/exceptions.h"
 
 #include "asiolink/io_address.h"
+#include "util/io_utilities.h"
 #include "dhcp/libdhcp.h"
 #include "dhcp/option6_addrlst.h"
 #include "dhcp/dhcp6.h"
@@ -26,7 +27,7 @@ using namespace std;
 using namespace isc;
 using namespace isc::dhcp;
 using namespace isc::asiolink;
-
+using namespace isc::util;
 
 Option6AddrLst::Option6AddrLst(unsigned short type,
                                const AddressContainer& addrs)
@@ -59,7 +60,7 @@ Option6AddrLst::setAddresses(const AddressContainer& addrs) {
 }
 
 unsigned int
-Option6AddrLst::pack(boost::shared_array<uint8_t> buf,
+Option6AddrLst::pack(boost::shared_array<uint8_t>& buf,
                     unsigned int buf_len,
                     unsigned int offset) {
     if (len() > buf_len) {
@@ -67,13 +68,16 @@ Option6AddrLst::pack(boost::shared_array<uint8_t> buf,
                   << ", buffer=" << buf_len << ": too small buffer.");
     }
 
-    *(uint16_t*)&buf[offset] = htons(type_);
-    offset += 2;
-    *(uint16_t*)&buf[offset] = htons(len()-4); // len() returns complete option
-    // length. len field contains length without 4-byte option header
-    offset += 2;
+    writeUint16(type_, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    // 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);
 
-    for (std::vector<IOAddress>::const_iterator addr=addrs_.begin();
+    // this wrapping is *ugly*. I wish there was a a
+    for (AddressContainer::const_iterator addr=addrs_.begin();
          addr!=addrs_.end();
          ++addr) {
         memcpy(&buf[offset],
@@ -86,10 +90,10 @@ Option6AddrLst::pack(boost::shared_array<uint8_t> buf,
 }
 
 unsigned int
-Option6AddrLst::unpack(boost::shared_array<uint8_t> buf,
-                  unsigned int buf_len,
-                  unsigned int offset,
-                  unsigned int option_len) {
+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) {
         isc_throw(OutOfRange, "Option " << type_
                   << " truncated.");
diff --git a/src/lib/dhcp/option6_addrlst.h b/src/lib/dhcp/option6_addrlst.h
index c3abf1b..c5b32af 100644
--- a/src/lib/dhcp/option6_addrlst.h
+++ b/src/lib/dhcp/option6_addrlst.h
@@ -71,7 +71,7 @@ public:
     /// @return offset to the next unused char (just after stored option)
     ///
     unsigned int
-    pack(boost::shared_array<uint8_t> buf, unsigned int buf_len,
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
          unsigned int offset);
 
     /// @brief Parses received data
@@ -84,7 +84,7 @@ public:
     /// @return offset to the next unparsed char (just after parsed option)
     ///
     virtual unsigned int
-    unpack(boost::shared_array<uint8_t> buf,
+    unpack(const boost::shared_array<uint8_t>& buf,
            unsigned int buf_len,
            unsigned int offset,
            unsigned int parse_len);
diff --git a/src/lib/dhcp/option6_ia.cc b/src/lib/dhcp/option6_ia.cc
index 345bbe3..350b32e 100644
--- a/src/lib/dhcp/option6_ia.cc
+++ b/src/lib/dhcp/option6_ia.cc
@@ -17,29 +17,31 @@
 #include <sstream>
 #include "exceptions/exceptions.h"
 
-#include "libdhcp.h"
-#include "option6_ia.h"
-#include "dhcp6.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;
 using namespace isc::dhcp;
+using namespace isc::util;
 
 Option6IA::Option6IA(unsigned short type, unsigned int iaid)
     :Option(Option::V6, type), iaid_(iaid) {
 }
 
 Option6IA::Option6IA(unsigned short type,
-                   boost::shared_array<uint8_t> buf,
-                   unsigned int buf_len,
-                   unsigned int offset,
-                   unsigned int option_len)
+                     const boost::shared_array<uint8_t>& buf,
+                     unsigned int buf_len,
+                     unsigned int offset,
+                     unsigned int option_len)
     :Option(Option::V6, type) {
     unpack(buf, buf_len, offset, option_len);
 }
 
 unsigned int
-Option6IA::pack(boost::shared_array<uint8_t> buf,
+Option6IA::pack(boost::shared_array<uint8_t>& buf,
                 unsigned int buf_len,
                 unsigned int offset) {
     if (offset + len() > buf_len) {
@@ -52,12 +54,14 @@ Option6IA::pack(boost::shared_array<uint8_t> buf,
                   << len() << " is too small (at least 16 is required).");
     }
 
+    writeUint16(type_, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    writeUint16(len() - OPTION6_HDR_LEN, &buf[offset]);
+    offset += sizeof(uint16_t);
+
+    /// TODO start using writeUint32 once such function is implemented
     uint8_t* ptr = &buf[offset];
-    *(uint16_t*)ptr = htons(type_);
-    ptr += sizeof(uint16_t);
-    *(uint16_t*)ptr = htons(len() - 4); // len() returns complete option length
-    // len field contains length without 4-byte option header
-    ptr += sizeof(uint16_t);
 
     *(uint32_t*)ptr = htonl(iaid_);
     ptr += sizeof(uint32_t);
@@ -68,12 +72,12 @@ Option6IA::pack(boost::shared_array<uint8_t> buf,
     *(uint32_t*)ptr = htonl(t2_);
     ptr += sizeof(uint32_t);
 
-    offset = LibDHCP::packOptions6(buf, buf_len, offset+16, options_);
+    offset = LibDHCP::packOptions6(buf, buf_len, offset+12, options_);
     return offset;
 }
 
 unsigned int
-Option6IA::unpack(boost::shared_array<uint8_t> buf,
+Option6IA::unpack(const boost::shared_array<uint8_t>& buf,
                   unsigned int buf_len,
                   unsigned int offset,
                   unsigned int parse_len) {
diff --git a/src/lib/dhcp/option6_ia.h b/src/lib/dhcp/option6_ia.h
index 9511076..7da2945 100644
--- a/src/lib/dhcp/option6_ia.h
+++ b/src/lib/dhcp/option6_ia.h
@@ -15,6 +15,7 @@
 #ifndef OPTION_IA_H_
 #define OPTION_IA_H_
 
+#include <stdint.h>
 #include "option.h"
 
 namespace isc {
@@ -30,7 +31,7 @@ public:
     ///
     /// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
     /// @param iaid identity association identifier (id of IA)
-    Option6IA(unsigned short type, unsigned int iaid);
+    Option6IA(uint16_t type, unsigned int iaid);
 
     /// @brief ctor, used for received options
     ///
@@ -45,7 +46,7 @@ public:
     /// @param buf_len buffer length
     /// @param offset offset in buffer
     /// @param len number of bytes to parse
-    Option6IA(unsigned short type, boost::shared_array<uint8_t> buf,
+    Option6IA(uint16_t type, const boost::shared_array<uint8_t>& buf,
               unsigned int buf_len, unsigned int offset, unsigned int len);
 
     /// Writes option in wire-format to buf, returns pointer to first unused
@@ -57,7 +58,7 @@ public:
     ///
     /// @return offset to the first unused byte after stored option
     unsigned int
-    pack(boost::shared_array<uint8_t> buf, unsigned int buf_len,
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
          unsigned int offset);
 
     /// @brief Parses received buffer
@@ -72,7 +73,7 @@ public:
     ///
     /// @return offset after last parsed octet
     virtual unsigned int
-    unpack(boost::shared_array<uint8_t> buf, unsigned int buf_len,
+    unpack(const boost::shared_array<uint8_t>& buf, unsigned int buf_len,
            unsigned int offset, unsigned int parse_len);
 
     /// Provides human readable text representation
diff --git a/src/lib/dhcp/option6_iaaddr.cc b/src/lib/dhcp/option6_iaaddr.cc
index 82f4400..56b7ba0 100644
--- a/src/lib/dhcp/option6_iaaddr.cc
+++ b/src/lib/dhcp/option6_iaaddr.cc
@@ -21,11 +21,13 @@
 #include "dhcp/option6_iaaddr.h"
 #include "dhcp/dhcp6.h"
 #include "asiolink/io_address.h"
+#include "util/io_utilities.h"
 
 using namespace std;
 using namespace isc;
 using namespace isc::dhcp;
 using namespace isc::asiolink;
+using namespace isc::util;
 
 Option6IAAddr::Option6IAAddr(unsigned short type,
                              const isc::asiolink::IOAddress& addr,
@@ -43,7 +45,7 @@ Option6IAAddr::Option6IAAddr(unsigned short type,
 }
 
 unsigned int
-Option6IAAddr::pack(boost::shared_array<uint8_t> buf,
+Option6IAAddr::pack(boost::shared_array<uint8_t>& buf,
                     unsigned int buf_len,
                     unsigned int offset) {
     if (len() > buf_len) {
@@ -71,7 +73,7 @@ Option6IAAddr::pack(boost::shared_array<uint8_t> buf,
 }
 
 unsigned int
-Option6IAAddr::unpack(boost::shared_array<uint8_t> buf,
+Option6IAAddr::unpack(const boost::shared_array<uint8_t>& buf,
                   unsigned int buf_len,
                   unsigned int offset,
                   unsigned int parse_len) {
diff --git a/src/lib/dhcp/option6_iaaddr.h b/src/lib/dhcp/option6_iaaddr.h
index 38e3386..26391bc 100644
--- a/src/lib/dhcp/option6_iaaddr.h
+++ b/src/lib/dhcp/option6_iaaddr.h
@@ -61,7 +61,7 @@ public:
     ///
     /// @return offset to first unused byte after stored option
     unsigned int
-    pack(boost::shared_array<uint8_t> buf, unsigned int buf_len,
+    pack(boost::shared_array<uint8_t>& buf, unsigned int buf_len,
          unsigned int offset);
 
     /// @brief Parses buffer.
@@ -76,7 +76,7 @@ public:
     ///
     /// @return offset after last parsed octet
     virtual unsigned int
-    unpack(boost::shared_array<uint8_t> buf,
+    unpack(const boost::shared_array<uint8_t>& buf,
            unsigned int buf_len,
            unsigned int offset,
            unsigned int parse_len);
diff --git a/src/lib/dhcp/pkt6.cc b/src/lib/dhcp/pkt6.cc
index 23daff4..65bd95e 100644
--- a/src/lib/dhcp/pkt6.cc
+++ b/src/lib/dhcp/pkt6.cc
@@ -114,7 +114,6 @@ Pkt6::packUDP() {
                                                       4/*offset*/,
                                                       options_);
 
-
         // sanity check
         if (offset != length) {
             isc_throw(OutOfRange, "Packet build failed: expected size="
diff --git a/src/lib/dhcp/pkt6.h b/src/lib/dhcp/pkt6.h
index af0761e..35bccbc 100644
--- a/src/lib/dhcp/pkt6.h
+++ b/src/lib/dhcp/pkt6.h
@@ -84,7 +84,7 @@ public:
     /// @param proto protocol (UDP or TCP)
     ///
     void
-    setProto(DHCPv6Proto proto = UDP);
+    setProto(DHCPv6Proto proto = UDP) { proto_ = proto; }
 
     /// @brief Returns text representation of the packet.
     ///
diff --git a/src/lib/dhcp/tests/option6_addrlst_unittest.cc b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
index 59fbaad..66dad34 100644
--- a/src/lib/dhcp/tests/option6_addrlst_unittest.cc
+++ b/src/lib/dhcp/tests/option6_addrlst_unittest.cc
@@ -106,12 +106,10 @@ TEST_F(Option6AddrLstTest, basic) {
     memcpy(&buf[0], sampledata, 48);
 
     // just a single address
-    Option6AddrLst* opt1 = new Option6AddrLst(D6O_NAME_SERVERS,
-                                              buf,
-                                              128,
-                                              0,
-                                              16);
-
+    Option6AddrLst* opt1;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(D6O_NAME_SERVERS, buf, 128, 0, 16);
+    );
 
     EXPECT_EQ(D6O_NAME_SERVERS, opt1->getType());
     EXPECT_EQ(20, opt1->len());
@@ -128,11 +126,10 @@ TEST_F(Option6AddrLstTest, basic) {
     EXPECT_EQ( 0, memcmp(expected1, &buf[100], 20) );
 
     // two addresses
-    Option6AddrLst* opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR,
-                                              buf,
-                                              128,
-                                              0,
-                                              32);
+    Option6AddrLst* opt2;
+    EXPECT_NO_THROW(
+        opt2 = new Option6AddrLst(D6O_SIP_SERVERS_ADDR, buf, 128, 0, 32);
+    );
     EXPECT_EQ(D6O_SIP_SERVERS_ADDR, opt2->getType());
     EXPECT_EQ(36, opt2->len());
     addrs = opt2->getAddresses();
@@ -147,13 +144,11 @@ TEST_F(Option6AddrLstTest, basic) {
     EXPECT_EQ(150+36, offset);
     EXPECT_EQ( 0, memcmp(expected2, &buf[150], 36));
 
-
     // three addresses
-    Option6AddrLst* opt3 = new Option6AddrLst(D6O_NIS_SERVERS,
-                                              buf,
-                                              128,
-                                              0,
-                                              48);
+    Option6AddrLst* opt3;
+    EXPECT_NO_THROW(
+        opt3 = new Option6AddrLst(D6O_NIS_SERVERS, buf, 128, 0, 48);
+    );
 
     EXPECT_EQ(D6O_NIS_SERVERS, opt3->getType());
     EXPECT_EQ(52, opt3->len());
@@ -170,46 +165,59 @@ TEST_F(Option6AddrLstTest, basic) {
     EXPECT_EQ(252, offset);
     EXPECT_EQ( 0, memcmp(expected3, &buf[200], 52) );
 
-    delete opt1;
-    delete opt2;
-    delete opt3;
+    EXPECT_NO_THROW(
+        delete opt1;
+        delete opt2;
+        delete opt3;
+    );
 }
 
 TEST_F(Option6AddrLstTest, constructors) {
-     Option6AddrLst * opt1 = new Option6AddrLst(1234,
-                                                IOAddress("::1"));
-     EXPECT_EQ(1234, opt1->getType());
-
-     Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
-     ASSERT_EQ(1, addrs.size() );
-     EXPECT_EQ("::1", addrs[0].toText());
-
-     addrs.clear();
-     addrs.push_back(IOAddress(string("fe80::1234")));
-     addrs.push_back(IOAddress(string("2001:db8:1::baca")));
 
-     Option6AddrLst * opt2 = new Option6AddrLst(5678,
-                                                addrs);
+    Option6AddrLst* opt1;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(1234, IOAddress("::1"));
+    );
+    EXPECT_EQ(1234, opt1->getType());
 
-     Option6AddrLst::AddressContainer check = opt2->getAddresses();
-     ASSERT_EQ(2, check.size() );
-     EXPECT_EQ("fe80::1234", check[0].toText());
-     EXPECT_EQ("2001:db8:1::baca", check[1].toText());
-
-     delete opt1;
-     delete opt2;
+    Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
+    ASSERT_EQ(1, addrs.size() );
+    EXPECT_EQ("::1", addrs[0].toText());
+
+    addrs.clear();
+    addrs.push_back(IOAddress(string("fe80::1234")));
+    addrs.push_back(IOAddress(string("2001:db8:1::baca")));
+
+    Option6AddrLst* opt2;
+    EXPECT_NO_THROW(
+        opt2 = new Option6AddrLst(5678, addrs);
+    );
+
+    Option6AddrLst::AddressContainer check = opt2->getAddresses();
+    ASSERT_EQ(2, check.size() );
+    EXPECT_EQ("fe80::1234", check[0].toText());
+    EXPECT_EQ("2001:db8:1::baca", check[1].toText());
+
+    EXPECT_NO_THROW(
+        delete opt1;
+        delete opt2;
+    );
 }
 
 TEST_F(Option6AddrLstTest, setAddress) {
-    Option6AddrLst * opt1 = new Option6AddrLst(1234,
-                                                IOAddress("::1"));
+    Option6AddrLst* opt1;
+    EXPECT_NO_THROW(
+        opt1 = new Option6AddrLst(1234, IOAddress("::1"));
+    );
     opt1->setAddress(IOAddress("::2"));
 
     Option6AddrLst::AddressContainer addrs = opt1->getAddresses();
     ASSERT_EQ(1, addrs.size() );
     EXPECT_EQ("::2", addrs[0].toText());
 
-    delete opt1;
+    EXPECT_NO_THROW(
+        delete opt1;
+    );
 }
 
 } // namespace




More information about the bind10-changes mailing list