Browse Source

[3546] Pkt class added.

Tomek Mrugalski 10 years ago
parent
commit
d7f6665faa
6 changed files with 276 additions and 324 deletions
  1. 1 0
      src/lib/dhcp/Makefile.am
  2. 240 0
      src/lib/dhcp/pkt.h
  3. 10 29
      src/lib/dhcp/pkt4.cc
  4. 7 109
      src/lib/dhcp/pkt4.h
  5. 11 53
      src/lib/dhcp/pkt6.cc
  6. 7 133
      src/lib/dhcp/pkt6.h

+ 1 - 0
src/lib/dhcp/Makefile.am

@@ -43,6 +43,7 @@ libkea_dhcp___la_SOURCES += option_definition.cc option_definition.h
 libkea_dhcp___la_SOURCES += option_space.cc option_space.h
 libkea_dhcp___la_SOURCES += option_string.cc option_string.h
 libkea_dhcp___la_SOURCES += protocol_util.cc protocol_util.h
+libkea_dhcp___la_SOURCES += pkt.cc pkt.h
 libkea_dhcp___la_SOURCES += pkt6.cc pkt6.h
 libkea_dhcp___la_SOURCES += pkt4.cc pkt4.h
 libkea_dhcp___la_SOURCES += pkt_filter.h pkt_filter.cc

+ 240 - 0
src/lib/dhcp/pkt.h

@@ -0,0 +1,240 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef PKT_H
+#define PKT_H
+
+#include <asiolink/io_address.h>
+#include <util/buffer.h>
+#include <dhcp/option.h>
+#include <dhcp/classify.h>
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace isc {
+
+namespace dhcp {
+
+/// @brief Base class for DHCPv4 (Pkt4) and DHCPv6 (Pkt6) classes
+///
+/// This is a base class that holds all common information (e.g. source and
+/// destination ports) and operations (e.g. add, get, delete options).
+/// This class is purely virtual. Please instantiate Pkt4, Pkt6 or any
+/// other derived classes.
+class Pkt {
+protected:
+Pkt(uint32_t transid, const isc::asiolink::IOAddress& local_addr,
+    const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
+    uint16_t remote_port)
+        :transid_(transid),
+        iface_(""),
+        ifindex_(-1),
+        local_addr_(local_addr),
+        remote_addr_(remote_addr),
+        local_port_(local_port),
+        remote_port_(remote_port),
+        buffer_out_(0)
+        {
+        }
+
+    Pkt(const uint8_t* buf, uint32_t len, const isc::asiolink::IOAddress& local_addr,
+        const isc::asiolink::IOAddress& remote_addr, uint16_t local_port,
+        uint16_t remote_port)
+       :transid_(0),
+        iface_(""),
+        ifindex_(-1),
+        local_addr_(local_addr),
+        remote_addr_(remote_addr),
+        local_port_(local_port),
+        remote_port_(remote_port),
+        buffer_out_(0)
+    {
+        data_.resize(len);
+        memcpy(&data_[0], buf, len);
+    }
+
+public:
+
+    virtual void pack() = 0;
+    //virtual bool unpack() = 0;
+
+    /// @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 Pkt{4,6} object is valid.
+    ///
+    /// RX packet or TX packet before pack() will return buffer with
+    /// zero length. This buffer is returned as non-const, so hooks
+    /// framework (and user's callouts) can modify them if needed
+    ///
+    /// @return reference to output buffer
+    isc::util::OutputBuffer& getBuffer() { return (buffer_out_); };
+
+    /// Adds an option to this packet.
+    ///
+    /// Sadly, we need to have 2 versions of that method. One that
+    /// accepts duplicates (DHCPv6) and one that does not (DHCPv4)
+    ///
+    /// @param opt option to be added.
+    virtual void addOption(const OptionPtr& opt);
+
+    /// 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(uint16_t type);
+
+    virtual std::string toText() = 0;
+
+    /// Returns packet type
+    ///
+    /// For DHCPv6, this is a straightforward operation (read packet field), but
+    /// for DHCPv4 it requires finding appropriate option (that may or may not
+    /// be present).
+    virtual size_t len() = 0;
+
+    /// Returns message type (e.g. 1 = SOLICIT)
+    ///
+    /// @return message type
+    virtual uint8_t getType() const = 0;
+
+    /// Sets message type (e.g. 1 = SOLICIT)
+    ///
+    /// @param type message type to be set
+    virtual void setType(uint8_t type) = 0;
+
+    /// @brief Sets transaction-id value
+    ///
+    /// @param transid transaction-id to be set.
+    void setTransid(uint32_t transid) { transid_ = transid; }
+
+    /// Returns value of transaction-id field
+    ///
+    /// @return transaction-id
+    uint32_t getTransid() const { return (transid_); };
+
+    /// @brief Classes this packet belongs to.
+    ///
+    /// This field is public, so the code outside of Pkt4 or Pkt6 class can
+    /// iterate over existing classes. Having it public also solves the problem
+    /// of returned reference lifetime. It is preferred to use @ref inClass and
+    /// @ref addClass should be used to operate on this field.
+    ClientClasses classes_;
+
+    /// @brief Checks whether a client belongs to a given class
+    ///
+    /// @param client_class name of the class
+    /// @return true if belongs
+    bool inClass(const isc::dhcp::ClientClass& client_class);
+
+    /// @brief Adds packet to a specified class
+    ///
+    /// A packet can be added to the same class repeatedly. Any additional
+    /// attempts to add to a class the packet already belongs to, will be
+    /// ignored silently.
+    ///
+    /// @note It is a matter of naming convention. Conceptually, the server
+    /// processes a stream of packets, with some packets belonging to given
+    /// classes. From that perspective, this method adds a packet to specifed
+    /// class. Implementation wise, it looks the opposite - the class name
+    /// is added to the packet. Perhaps the most appropriate name for this
+    /// method would be associateWithClass()? But that seems overly long,
+    /// so I decided to stick with addClass().
+    ///
+    /// @param client_class name of the class to be added
+    void addClass(const isc::dhcp::ClientClass& client_class);
+
+    /// unparsed data (in received packets)
+    ///
+    /// @warning This public member is accessed by derived
+    /// classes directly. One of such derived classes is
+    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
+    /// behavior must be taken into consideration before making
+    /// changes to this member such as access scope restriction or
+    /// data format change etc.
+    OptionBuffer data_;
+
+    virtual ~Pkt() { }
+
+protected:
+
+    /// transaction-id (32 bits for v4, 24 bits for v6)
+    uint32_t transid_;
+
+    /// 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 equivalent 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
+    uint16_t local_port_;
+
+    /// remote TCP or UDP port
+    uint16_t remote_port_;
+
+    /// collection of options present in this message
+    ///
+    /// @warning This public member is accessed by derived
+    /// classes directly. One of such derived classes is
+    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
+    /// behavior must be taken into consideration before making
+    /// changes to this member such as access scope restriction or
+    /// data format change etc.
+    isc::dhcp::OptionCollection options_;
+
+    /// Output buffer (used during message transmission)
+    ///
+    /// @warning This protected member is accessed by derived
+    /// classes directly. One of such derived classes is
+    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
+    /// behavior must be taken into consideration before making
+    /// changes to this member such as access scope restriction or
+    /// data format change etc.
+    ///
+    /// @warning This public member is accessed by derived
+    /// classes directly. One of such derived classes is
+    /// @ref perfdhcp::PerfPkt4. The impact on derived clasess'
+    /// behavior must be taken into consideration before making
+    /// changes to this member such as access scope restriction or
+    /// data format change etc. This field is also public, because
+    /// it may be modified by callouts (which are written in C++ now,
+    /// but we expect to also have them in Python, so any accesibility
+    /// methods would overly complicate things here and degrade
+    /// performance).
+    isc::util::OutputBuffer buffer_out_;
+
+    /// packet timestamp
+    boost::posix_time::ptime timestamp_;
+
+    /// A callback to be called to unpack options from the packet.
+    UnpackOptionsCallback callback_;
+};
+
+}; // namespace isc::dhcp
+}; // namespace isc
+
+#endif

+ 10 - 29
src/lib/dhcp/pkt4.cc

@@ -33,17 +33,11 @@ namespace dhcp {
 const IOAddress DEFAULT_ADDRESS("0.0.0.0");
 
 Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
-     :buffer_out_(DHCPV4_PKT_HDR_LEN),
-      local_addr_(DEFAULT_ADDRESS),
-      remote_addr_(DEFAULT_ADDRESS),
-      iface_(""),
-      ifindex_(0),
-      local_port_(DHCP4_SERVER_PORT),
-      remote_port_(DHCP4_CLIENT_PORT),
+     :Pkt(transid, DEFAULT_ADDRESS, DEFAULT_ADDRESS, DHCP4_SERVER_PORT,
+          DHCP4_CLIENT_PORT),
       op_(DHCPTypeToBootpType(msg_type)),
       hwaddr_(new HWAddr()),
       hops_(0),
-      transid_(transid),
       secs_(0),
       flags_(0),
       ciaddr_(DEFAULT_ADDRESS),
@@ -51,6 +45,7 @@ Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
       siaddr_(DEFAULT_ADDRESS),
       giaddr_(DEFAULT_ADDRESS)
 {
+    // buffer_out_.resize(DHCPV4_PKT_HDR_LEN);
     memset(sname_, 0, MAX_SNAME_LEN);
     memset(file_, 0, MAX_FILE_LEN);
 
@@ -58,17 +53,11 @@ Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
 }
 
 Pkt4::Pkt4(const uint8_t* data, size_t len)
-     :buffer_out_(0), // not used, this is RX packet
-      local_addr_(DEFAULT_ADDRESS),
-      remote_addr_(DEFAULT_ADDRESS),
-      iface_(""),
-      ifindex_(0),
-      local_port_(DHCP4_SERVER_PORT),
-      remote_port_(DHCP4_CLIENT_PORT),
+     :Pkt(data, len, DEFAULT_ADDRESS, DEFAULT_ADDRESS, DHCP4_SERVER_PORT,
+          DHCP4_CLIENT_PORT),
       op_(BOOTREQUEST),
       hwaddr_(new HWAddr()),
       hops_(0),
-      transid_(0),
       secs_(0),
       flags_(0),
       ciaddr_(DEFAULT_ADDRESS),
@@ -76,6 +65,7 @@ Pkt4::Pkt4(const uint8_t* data, size_t len)
       siaddr_(DEFAULT_ADDRESS),
       giaddr_(DEFAULT_ADDRESS)
 {
+
     if (len < DHCPV4_PKT_HDR_LEN) {
         isc_throw(OutOfRange, "Truncated DHCPv4 packet (len=" << len
                   << ") received, at least " << DHCPV4_PKT_HDR_LEN
@@ -163,7 +153,7 @@ Pkt4::pack() {
     }
 }
 
-void
+bool
 Pkt4::unpack() {
 
     // input buffer (used during message reception)
@@ -232,6 +222,8 @@ Pkt4::unpack() {
     // @todo check will need to be called separately, so hooks can be called
     // after the packet is parsed, but before its content is verified
     check();
+
+    return (true);
 }
 
 void Pkt4::check() {
@@ -433,7 +425,7 @@ Pkt4::getHlen() const {
 }
 
 void
-Pkt4::addOption(boost::shared_ptr<Option> opt) {
+Pkt4::addOption(const OptionPtr& opt) {
     // Check for uniqueness (DHCPv4 options must be unique)
     if (getOption(opt->getType())) {
         isc_throw(BadValue, "Option " << opt->getType()
@@ -485,17 +477,6 @@ Pkt4::isRelayed() const {
               "hops != 0)");
 }
 
-bool Pkt4::inClass(const isc::dhcp::ClientClass& client_class) {
-    return (classes_.find(client_class) != classes_.end());
-}
-
-void
-Pkt4::addClass(const isc::dhcp::ClientClass& client_class) {
-    if (classes_.find(client_class) == classes_.end()) {
-        classes_.insert(client_class);
-    }
-}
-
 } // end of namespace isc::dhcp
 
 } // end of namespace isc

+ 7 - 109
src/lib/dhcp/pkt4.h

@@ -21,8 +21,8 @@
 #include <dhcp/option.h>
 #include <dhcp/hwaddr.h>
 #include <dhcp/classify.h>
+#include <dhcp/pkt.h>
 
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/shared_ptr.hpp>
 
 #include <iostream>
@@ -35,7 +35,7 @@ namespace isc {
 
 namespace dhcp {
 
-class Pkt4 {
+class Pkt4 : public Pkt {
 public:
 
     /// length of the CHADDR field in DHCPv4 message
@@ -88,7 +88,8 @@ public:
     /// be stored in options_ container.
     ///
     /// Method with throw exception if packet parsing fails.
-    void unpack();
+    /// @return true if unpack was successful
+    bool unpack();
 
     /// @brief performs sanity check on a packet.
     ///
@@ -216,16 +217,6 @@ public:
     void
     setGiaddr(const isc::asiolink::IOAddress& giaddr) { giaddr_ = giaddr; };
 
-    /// @brief Sets transaction-id value
-    ///
-    /// @param transid transaction-id to be set.
-    void setTransid(uint32_t transid) { transid_ = transid; }
-
-    /// @brief Returns value of transaction-id field.
-    ///
-    /// @return transaction-id
-    uint32_t getTransid() const { return (transid_); };
-
     /// @brief Returns DHCP message type (e.g. 1 = DHCPDISCOVER).
     ///
     /// @return message type
@@ -304,33 +295,19 @@ public:
     /// @return hardware address structure
     HWAddrPtr getHWAddr() const { return (hwaddr_); }
 
-    /// @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. This buffer is returned as non-const, so hooks
-    /// framework (and user's callouts) can modify them if needed
-    ///
-    /// @return reference to output buffer
-    isc::util::OutputBuffer&
-    getBuffer() { return (buffer_out_); };
-
     /// @brief Add an option.
     ///
     /// Throws BadValue if option with that type is already present.
     ///
     /// @param opt option to be added
-    void
-    addOption(boost::shared_ptr<Option> opt);
+    virtual void
+    addOption(const OptionPtr& opt);
 
     /// @brief Returns an option of specified type.
     ///
     /// @return returns option of requested type (or NULL)
     ///         if no such option is present
-    boost::shared_ptr<Option>
+    OptionPtr
     getOption(uint8_t opt_type) const;
 
     /// @brief Deletes specified option
@@ -520,20 +497,6 @@ public:
     /// @throw isc::Unexpected if timestamp update failed
     void updateTimestamp();
 
-    /// Output buffer (used during message transmission)
-    ///
-    /// @warning This public member is accessed by derived
-    /// classes directly. One of such derived classes is
-    /// @ref perfdhcp::PerfPkt4. The impact on derived clasess'
-    /// behavior must be taken into consideration before making
-    /// changes to this member such as access scope restriction or
-    /// data format change etc. This field is also public, because
-    /// it may be modified by callouts (which are written in C++ now,
-    /// but we expect to also have them in Python, so any accesibility
-    /// methods would overly complicate things here and degrade
-    /// performance).
-    isc::util::OutputBuffer buffer_out_;
-
     /// @brief That's the data of input buffer used in RX packet.
     ///
     /// @note Note that InputBuffer does not store the data itself, but just
@@ -552,36 +515,6 @@ public:
     /// performance).
     std::vector<uint8_t> data_;
 
-    /// @brief Checks whether a client belongs to a given class
-    ///
-    /// @param client_class name of the class
-    /// @return true if belongs
-    bool inClass(const isc::dhcp::ClientClass& client_class);
-
-    /// @brief Adds packet to a specified class
-    ///
-    /// A packet can be added to the same class repeatedly. Any additional
-    /// attempts to add to a class the packet already belongs to, will be
-    /// ignored silently.
-    ///
-    /// @note It is a matter of naming convention. Conceptually, the server
-    /// processes a stream of packets, with some packets belonging to given
-    /// classes. From that perspective, this method adds a packet to specifed
-    /// class. Implementation wise, it looks the opposite - the class name
-    /// is added to the packet. Perhaps the most appropriate name for this
-    /// method would be associateWithClass()? But that seems overly long,
-    /// so I decided to stick with addClass().
-    ///
-    /// @param client_class name of the class to be added
-    void addClass(const isc::dhcp::ClientClass& client_class);
-
-    /// @brief Classes this packet belongs to.
-    ///
-    /// This field is public, so the code outside of Pkt4 class can iterate over
-    /// existing classes. Having it public also solves the problem of returned
-    /// reference lifetime. It is preferred to use @ref inClass and @ref addClass
-    /// should be used to operate on this field.
-    ClientClasses classes_;
 
 private:
 
@@ -616,28 +549,6 @@ protected:
     // remote HW address (src if receiving packet, dst if sending packet)
     HWAddrPtr remote_hwaddr_;
 
-    /// 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_;
-
-    /// name of the network interface the packet was received/to be sent over
-    std::string iface_;
-
-    /// @brief interface index
-    ///
-    /// Each network interface has assigned unique ifindex. It is functional
-    /// equivalent of name, but sometimes more useful, e.g. when using crazy
-    /// systems that allow spaces in interface names e.g. MS Windows)
-    uint32_t ifindex_;
-
-    /// local UDP port
-    uint16_t local_port_;
-
-    /// remote UDP port
-    uint16_t remote_port_;
-
     /// @brief message operation code
     ///
     /// Note: This is legacy BOOTP field. There's no need to manipulate it
@@ -656,9 +567,6 @@ protected:
     /// Number of relay agents traversed
     uint8_t hops_;
 
-    /// DHCPv4 transaction-id (32 bits, not 24 bits as in DHCPv6)
-    uint32_t transid_;
-
     /// elapsed (number of seconds since beginning of transmission)
     uint16_t secs_;
 
@@ -685,16 +593,6 @@ protected:
 
     // end of real DHCPv4 fields
 
-    /// collection of options present in this message
-    ///
-    /// @warning This protected member is accessed by derived
-    /// classes directly. One of such derived classes is
-    /// @ref perfdhcp::PerfPkt4. The impact on derived classes'
-    /// behavior must be taken into consideration before making
-    /// changes to this member such as access scope restriction or
-    /// data format change etc.
-    isc::dhcp::OptionCollection options_;
-
     /// packet timestamp
     boost::posix_time::ptime timestamp_;
 

+ 11 - 53
src/lib/dhcp/pkt6.cc

@@ -27,41 +27,26 @@ using namespace isc::asiolink;
 namespace isc {
 namespace dhcp {
 
+const IOAddress DEFAULT_ADDRESS6("::");
+
 Pkt6::RelayInfo::RelayInfo()
-    :msg_type_(0), hop_count_(0), linkaddr_("::"), peeraddr_("::"), relay_msg_len_(0) {
+    :msg_type_(0), hop_count_(0), linkaddr_("::"), peeraddr_("::"),
+    relay_msg_len_(0) {
     // interface_id_, subscriber_id_, remote_id_ initialized to NULL
     // echo_options_ initialized to empty collection
 }
 
-Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */) :
-    proto_(proto),
-    msg_type_(0),
-    transid_(rand()%0xffffff),
-    iface_(""),
-    ifindex_(-1),
-    local_addr_("::"),
-    remote_addr_("::"),
-    local_port_(0),
-    remote_port_(0),
-    buffer_out_(0) {
-    data_.resize(buf_len);
-    memcpy(&data_[0], buf, buf_len);
+Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */)
+   :Pkt(buf, buf_len, DEFAULT_ADDRESS6, DEFAULT_ADDRESS6, 0, 0),
+    proto_(proto), msg_type_(0) {
 }
 
-Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/) :
-    proto_(proto),
-    msg_type_(msg_type),
-    transid_(transid),
-    iface_(""),
-    ifindex_(-1),
-    local_addr_("::"),
-    remote_addr_("::"),
-    local_port_(0),
-    remote_port_(0),
-    buffer_out_(0) {
+Pkt6::Pkt6(uint8_t msg_type, uint32_t transid, DHCPv6Proto proto /*= UDP*/)
+:Pkt(transid, DEFAULT_ADDRESS6, DEFAULT_ADDRESS6, 0, 0), proto_(proto),
+    msg_type_(msg_type) {
 }
 
-uint16_t Pkt6::len() {
+size_t Pkt6::len() {
     if (relay_info_.empty()) {
         return (directLen());
     } else {
@@ -488,21 +473,6 @@ Pkt6::getOptions(uint16_t opt_type) {
     return (found);
 }
 
-void
-Pkt6::addOption(const OptionPtr& opt) {
-    options_.insert(pair<int, boost::shared_ptr<Option> >(opt->getType(), opt));
-}
-
-bool
-Pkt6::delOption(uint16_t type) {
-    isc::dhcp::OptionCollection::iterator x = options_.find(type);
-    if (x!=options_.end()) {
-        options_.erase(x);
-        return (true); // delete successful
-    }
-    return (false); // can't find option to be deleted
-}
-
 void Pkt6::repack() {
     buffer_out_.writeData(&data_[0], data_.size());
 }
@@ -586,17 +556,5 @@ void Pkt6::copyRelayInfo(const Pkt6Ptr& question) {
     }
 }
 
-bool
-Pkt6::inClass(const std::string& client_class) {
-    return (classes_.find(client_class) != classes_.end());
-}
-
-void
-Pkt6::addClass(const std::string& client_class) {
-    if (classes_.find(client_class) == classes_.end()) {
-        classes_.insert(client_class);
-    }
-}
-
 } // end of isc::dhcp namespace
 } // end of isc namespace

+ 7 - 133
src/lib/dhcp/pkt6.h

@@ -17,7 +17,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcp/option.h>
-#include <dhcp/classify.h>
+#include <dhcp/pkt.h>
 
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/shared_array.hpp>
@@ -35,7 +35,7 @@ namespace dhcp {
 class Pkt6;
 typedef boost::shared_ptr<Pkt6> Pkt6Ptr;
 
-class Pkt6 {
+class Pkt6 : public Pkt {
 public:
     /// specifies non-relayed DHCPv6 packet header length (over UDP)
     const static size_t DHCPV6_PKT_HDR_LEN = 4;
@@ -122,7 +122,7 @@ public:
     /// @throw BadValue if packet protocol is invalid, InvalidOperation
     /// if packing fails, or NotImplemented if protocol is TCP (IPv6 over TCP is
     /// not yet supported).
-    void pack();
+    virtual void pack();
 
     /// @brief Dispatch method that handles binary packet parsing.
     ///
@@ -130,19 +130,7 @@ public:
     /// unpackTCP).
     ///
     /// @return true if parsing was successful
-    bool unpack();
-
-    /// @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 Pkt6 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 (buffer_out_); };
+    virtual bool unpack();
 
     /// @brief Returns protocol of this packet (UDP or TCP).
     ///
@@ -159,7 +147,7 @@ public:
     /// This function is useful mainly for debugging.
     ///
     /// @return string with text representation
-    std::string toText();
+    virtual std::string toText();
 
     /// @brief Returns length of the packet.
     ///
@@ -171,33 +159,18 @@ public:
     /// before they are unpacked.
     ///
     /// @return number of bytes required to assemble this packet
-    uint16_t len();
+    virtual size_t len();
 
     /// Returns message type (e.g. 1 = SOLICIT)
     ///
     /// @return message type
-    uint8_t getType() const { return (msg_type_); }
+    virtual uint8_t getType() const { return (msg_type_); }
 
     /// Sets message type (e.g. 1 = SOLICIT)
     ///
     /// @param type message type to be set
     void setType(uint8_t type) { msg_type_=type; };
 
-    /// @brief Sets transaction-id value
-    ///
-    /// @param transid transaction-id to be set.
-    void setTransid(uint32_t transid) { transid_ = transid; }
-
-    /// Returns value of transaction-id field
-    ///
-    /// @return transaction-id
-    uint32_t getTransid() const { return (transid_); };
-
-    /// Adds an option to this packet.
-    ///
-    /// @param opt option to be added.
-    void addOption(const OptionPtr& opt);
-
     /// @brief Returns the first option of specified type.
     ///
     /// Returns the first option of specified type. Note that in DHCPv6 several
@@ -247,13 +220,6 @@ public:
     /// @return instance of option collection with requested options
     isc::dhcp::OptionCollection getOptions(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(uint16_t type);
-
     /// @brief This method copies data from output buffer to input buffer
     ///
     /// This is useful only in testing
@@ -345,16 +311,6 @@ public:
     /// @param relay structure with necessary relay information
     void addRelayInfo(const RelayInfo& relay);
 
-    /// collection of options present in this message
-    ///
-    /// @warning This public member is accessed by derived
-    /// classes directly. One of such derived classes is
-    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
-    /// behavior must be taken into consideration before making
-    /// changes to this member such as access scope restriction or
-    /// data format change etc.
-    isc::dhcp::OptionCollection options_;
-
     /// @brief Update packet timestamp.
     ///
     /// Updates packet timestamp. This method is invoked
@@ -417,46 +373,6 @@ public:
     /// (or least bad) solution.
     std::vector<RelayInfo> relay_info_;
 
-
-    /// unparsed data (in received packets)
-    ///
-    /// @warning This public member is accessed by derived
-    /// classes directly. One of such derived classes is
-    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
-    /// behavior must be taken into consideration before making
-    /// changes to this member such as access scope restriction or
-    /// data format change etc.
-    OptionBuffer data_;
-
-    /// @brief Checks whether a client belongs to a given class
-    ///
-    /// @param client_class name of the class
-    /// @return true if belongs
-    bool inClass(const std::string& client_class);
-
-    /// @brief Adds packet to a specified class
-    ///
-    /// A packet can be added to the same class repeatedly. Any additional
-    /// attempts to add to a class the packet already belongs to, will be
-    /// ignored silently.
-    ///
-    /// @note It is a matter of naming convention. Conceptually, the server
-    /// processes a stream of packets, with some packets belonging to given
-    /// classes. From that perspective, this method adds a packet to specifed
-    /// class. Implementation wise, it looks the opposite - the class name
-    /// is added to the packet. Perhaps the most appropriate name for this
-    /// method would be associateWithClass()? But that seems overly long,
-    /// so I decided to stick with addClass().
-    ///
-    /// @param client_class name of the class to be added
-    void addClass(const std::string& client_class);
-
-    /// @brief Classes this packet belongs to.
-    ///
-    /// This field is public, so code can iterate over existing classes.
-    /// Having it public also solves the problem of returned reference lifetime.
-    ClientClasses classes_;
-
 protected:
     /// Builds on wire packet for TCP transmission.
     ///
@@ -536,48 +452,6 @@ protected:
     /// DHCPv6 message type
     uint8_t msg_type_;
 
-    /// DHCPv6 transaction-id
-    uint32_t transid_;
-
-    /// 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 equivalent 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
-    uint16_t local_port_;
-
-    /// remote TCP or UDP port
-    uint16_t remote_port_;
-
-    /// Output buffer (used during message transmission)
-    ///
-    /// @warning This protected member is accessed by derived
-    /// classes directly. One of such derived classes is
-    /// @ref perfdhcp::PerfPkt6. The impact on derived clasess'
-    /// behavior must be taken into consideration before making
-    /// changes to this member such as access scope restriction or
-    /// data format change etc.
-    isc::util::OutputBuffer buffer_out_;
-
-    /// packet timestamp
-    boost::posix_time::ptime timestamp_;
-
-    /// A callback to be called to unpack options from the packet.
-    UnpackOptionsCallback callback_;
-
 }; // Pkt6 class
 
 } // isc::dhcp namespace