consequently moved all implementation from h to cpp files
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Fri, 13 Mar 2015 09:02:19 +0000 (10:02 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Fri, 13 Mar 2015 09:02:19 +0000 (10:02 +0100)
13 files changed:
src/CMakeLists.txt
src/icmp/icmpdata.cpp
src/icmp/icmpdata.h
src/icmp/icmpdestinationunreachabledata.cpp [new file with mode: 0644]
src/icmp/icmpdestinationunreachabledata.h
src/icmp/icmpechodata.cpp [new file with mode: 0644]
src/icmp/icmpechodata.h
src/icmp/icmpheader.cpp
src/icmp/icmpheader.h
src/icmp/icmppacket.cpp
src/icmp/icmppacket.h
test/CMakeLists.test_icmpv4header.txt
test/CMakeLists.test_icmpv6header.txt

index 4ea0ce9..b469bfd 100644 (file)
@@ -77,6 +77,8 @@ set(SOURCES
     host/pingrotate.cpp
     host/pingscheduler.cpp
     icmp/icmpdata.cpp
+    icmp/icmpechodata.cpp
+    icmp/icmpdestinationunreachabledata.cpp
     icmp/icmpheader.cpp
     icmp/icmppacket.cpp
     icmp/icmppinger.cpp
index 3506cc6..28d0849 100644 (file)
 
 #include <sstream>
 
+IcmpData::IcmpData()
+    : size( 0 )
+    , raw_data( 0 )
+{}
+
+IcmpData::IcmpData(const std::size_t size_arg)
+    : size( size_arg )
+    , raw_data( size_arg )
+{}
+
+bool IcmpData::match_echo_reply(const uint16_t identifier,
+                              const uint16_t sequence_number) const
+{  return false;  };
+
+bool IcmpData::match_destination_unreachable(const uint16_t identifier,
+                              const uint16_t sequence_number) const
+{  return false;  };
+
+inline std::size_t IcmpData::get_size()
+{  return size;  };
+
+uint32_t IcmpData::calc_checksum_part() const
+{  return raw_data.calc_checksum_part();  }
+
+
+void IcmpData::print( const size_t &bytes_received,
+                      const boost::posix_time::ptime &time_packet_sent,
+                      const std::string &remote_address,
+                      const uint32_t ttl) const
+{}
+
 std::istream& IcmpData::read(std::istream &is)  // read raw data
 {
     return raw_data.read(is);
index c920bd0..0eeae93 100644 (file)
 class IcmpData
 {
 public:
-    IcmpData()
-        : size( 0 )
-        , raw_data( 0 )
-    {}
+    IcmpData();
 
-    virtual ~IcmpData() {}
+    virtual ~IcmpData() {};
 
     virtual bool match_echo_reply(const uint16_t identifier,
-                                  const uint16_t sequence_number) const
-    {  return false;  };
+                                  const uint16_t sequence_number) const;
 
     virtual bool match_destination_unreachable(const uint16_t identifier,
-                                  const uint16_t sequence_number) const
-    {  return false;  };
+                                  const uint16_t sequence_number) const;
 
-    inline std::size_t get_size() { return size; };
+    inline std::size_t get_size();
 
     virtual std::istream& read( std::istream &is);
     virtual std::ostream& write(std::ostream &os) const;
 
-    inline uint32_t calc_checksum_part() const
-    {   return raw_data.calc_checksum_part();  }
+    uint32_t calc_checksum_part() const;
 
     virtual void print( const size_t &bytes_received,
                         const boost::posix_time::ptime &time_packet_sent,
                         const std::string &remote_address,
-                        const uint32_t ttl) const
-    {}
+                        const uint32_t ttl) const;
 
     virtual std::string to_string() const;
 
@@ -80,10 +73,8 @@ public:
 
 protected:
 
-    IcmpData(const std::size_t size_arg)
-        : size( size_arg )
-        , raw_data( size_arg )
-    {}
+    // called by subclasses
+    IcmpData(const std::size_t size_arg);
 
     std::size_t size;
     MessagePayload raw_data;
diff --git a/src/icmp/icmpdestinationunreachabledata.cpp b/src/icmp/icmpdestinationunreachabledata.cpp
new file mode 100644 (file)
index 0000000..b627b1f
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+
+ Christian Herdtweck, Intra2net AG 2015
+ */
+
+#include "icmp/icmpdestinationunreachabledata.h"
+
+#include <logfunc.hpp>
+using I2n::Logger::GlobalLogger;
+
+
+IcmpDestinationUnreachableData::IcmpDestinationUnreachableData(
+                                                     const std::size_t size_arg)
+    : IcmpData( size_arg )
+{}
+
+bool IcmpDestinationUnreachableData::match_echo_reply(const uint16_t identifier,
+                      const uint16_t sequence_number) const
+{ return false; }
+
+bool IcmpDestinationUnreachableData::match_destination_unreachable(
+                                           const uint16_t identifier,
+                                           const uint16_t sequence_number) const
+{
+    return      identifier == get_icmp_identifier() &&
+           sequence_number == get_icmp_sequence_number();
+}
+
+
+uint16_t IcmpDestinationUnreachableData::get_icmp_identifier() const
+{ return get_icmp_request_data(5); }
+
+uint16_t IcmpDestinationUnreachableData::get_icmp_sequence_number() const
+{ return get_icmp_request_data(7); }
+
+uint16_t IcmpDestinationUnreachableData::get_icmp_request_data(
+                                                   const int data_offset) const
+{
+    // payload should be the original query, which is an IP packet.
+    // first check wheter that IP packet contains an ICMP message at all
+    bool is_icmp;
+    int offset = 4;   // the 4 uninteresting bytes we need to skip
+    if (IcmpData::raw_data[offset+0] == 4)   // IPv4
+    {
+        is_icmp = IcmpData::raw_data[offset+9] == 1;
+        offset += 20;     // 20 byte for IPv4 header
+    }
+    else if (IcmpData::raw_data[offset+0] == 6)   // IPv6
+    {
+        is_icmp = IcmpData::raw_data[offset+6] == 58;
+        offset += 40;     // 40 byte for IPv6 header
+    }
+
+    if ( !is_icmp )
+        return static_cast<uint16_t>(-1);
+    else
+        // if it is an icmp message, then the icmp packet comes right after
+        // the IP header. Inside the icmp packet we need bytes 5-8
+        return IcmpData::raw_data.decode16(offset+data_offset,
+                                           offset+data_offset+1);
+}
+
+/**
+ * @brief Prints the destination unreachable messages.
+ *
+ * @return void
+ */
+void IcmpDestinationUnreachableData::print(
+            const size_t &bytes_received,
+            const boost::posix_time::ptime &time_packet_sent,
+            const std::string &remote_address,
+            const uint32_t ttl) const
+{
+    uint16_t sequence_number = get_icmp_sequence_number();
+
+    GlobalLogger.info() << "Destination " << remote_address
+         << " (icmp_seq=" << sequence_number << ") unreachable!"
+         << std::endl;
+}
+
+// (created using vim -- the world's best text editor)
+
index 89fd257..22b5b6a 100644 (file)
@@ -28,9 +28,6 @@
 #include <boost/date_time/posix_time/ptime.hpp>
 #include "icmp/icmpdata.h"
 
-#include <logfunc.hpp>
-using I2n::Logger::GlobalLogger;
-
 /**
  * structure of these packets (if originated from an ICMP request):
  * +---------------------------+
@@ -62,70 +59,17 @@ using I2n::Logger::GlobalLogger;
 class IcmpDestinationUnreachableData : public IcmpData
 {
 public:
-    IcmpDestinationUnreachableData(const std::size_t size_arg)
-        : IcmpData( size_arg )
-    {}
+    IcmpDestinationUnreachableData(const std::size_t size_arg);
 
     bool match_echo_reply(const uint16_t identifier,
-                          const uint16_t sequence_number) const
-    { return false; }
+                          const uint16_t sequence_number) const;
 
     bool match_destination_unreachable(const uint16_t identifier,
-                                       const uint16_t sequence_number) const
-    {
-        // payload should be the original query, which is an IP packet.
-        // first check wheter that IP packet contains an ICMP message at all
-        bool is_icmp;
-        int offset = 4;   // the 4 uninteresting bytes we need to skip
-        if (IcmpData::raw_data[offset+0] == 4)   // IPv4
-        {
-            is_icmp = IcmpData::raw_data[offset+9] == 1;
-            offset += 20;     // 20 byte for IPv4 header
-        }
-        else if (IcmpData::raw_data[offset+0] == 6)   // IPv6
-        {
-            is_icmp = IcmpData::raw_data[offset+6] == 58;
-            offset += 40;     // 40 byte for IPv6 header
-        }
-
-        // if it is an icmp message, then the icmp packet comes right after the
-        // IP header. Inside the icmp packet we need bytes 5-8
-        return identifier == get_icmp_identifier() &&
-               sequence_number == get_icmp_sequence_number();
-    }
-
-
-    uint16_t get_icmp_identifier() const
-    { return get_icmp_request_data(5); }
-
-    uint16_t get_icmp_sequence_number() const
-    { return get_icmp_request_data(7); }
-
-    uint16_t get_icmp_request_data(const int data_offset) const
-    {
-        // payload should be the original query, which is an IP packet.
-        // first check wheter that IP packet contains an ICMP message at all
-        bool is_icmp;
-        int offset = 4;   // the 4 uninteresting bytes we need to skip
-        if (IcmpData::raw_data[offset+0] == 4)   // IPv4
-        {
-            is_icmp = IcmpData::raw_data[offset+9] == 1;
-            offset += 20;     // 20 byte for IPv4 header
-        }
-        else if (IcmpData::raw_data[offset+0] == 6)   // IPv6
-        {
-            is_icmp = IcmpData::raw_data[offset+6] == 58;
-            offset += 40;     // 40 byte for IPv6 header
-        }
-
-        if ( !is_icmp )
-            return static_cast<uint16_t>(-1);
-        else
-            // if it is an icmp message, then the icmp packet comes right after
-            // the IP header. Inside the icmp packet we need bytes 5-8
-            return IcmpData::raw_data.decode16(offset+data_offset,
-                                               offset+data_offset+1);
-    }
+                                       const uint16_t sequence_number) const;
+
+    uint16_t get_icmp_identifier() const;
+
+    uint16_t get_icmp_sequence_number() const;
 
     /**
      * @brief Prints the destination unreachable messages.
@@ -135,16 +79,10 @@ public:
     void print( const size_t &bytes_received,
                 const boost::posix_time::ptime &time_packet_sent,
                 const std::string &remote_address,
-                const uint32_t ttl) const
-    {
-        uint16_t sequence_number = get_icmp_sequence_number();
-
-        GlobalLogger.info() << "Destination " << remote_address
-             << " (icmp_seq=" << sequence_number << ") unreachable!"
-             << std::endl;
-    }
-
+                const uint32_t ttl) const;
 
+protected:
+    uint16_t get_icmp_request_data(const int data_offset) const;
 
 };
 
diff --git a/src/icmp/icmpechodata.cpp b/src/icmp/icmpechodata.cpp
new file mode 100644 (file)
index 0000000..06c27bc
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+
+ Christian Herdtweck, Intra2net AG 2015
+ */
+
+#include "icmp/icmpechodata.h"
+
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+#include "boost/date_time/time_resolution_traits.hpp"
+#include <logfunc.hpp>
+
+using boost::date_time::time_resolution_traits_adapted64_impl;
+using I2n::Logger::GlobalLogger;
+
+
+IcmpEchoData::IcmpEchoData(const uint16_t identifier,
+                           const uint16_t sequence_number,
+                           const std::string &optional_data)
+    : IcmpData( 4 + optional_data.length() )
+{
+    IcmpData::raw_data.encode16(0, 1, identifier);
+    IcmpData::raw_data.encode16(2, 3, sequence_number);
+    IcmpData::raw_data.encode_string(4, optional_data);
+    GlobalLogger.debug() << "Done creating echo request" << std::endl;
+}
+
+IcmpEchoData::IcmpEchoData(const std::size_t size_arg)
+    : IcmpData( size_arg )
+{}
+
+
+bool IcmpEchoData::match_destination_unreachable(
+                                    const uint16_t identifier,
+                                    const uint16_t sequence_number) const
+{ return false; }
+
+
+bool IcmpEchoData::match_echo_reply(const uint16_t identifier,
+                                    const uint16_t sequence_number) const
+{
+    return get_identifier() == identifier
+        && get_sequence_number() == sequence_number;
+}
+
+uint16_t IcmpEchoData::get_identifier() const
+{ return IcmpData::raw_data.decode16(0, 1);  }
+
+uint16_t IcmpEchoData::get_sequence_number() const
+{ return IcmpData::raw_data.decode16(2, 3);  }
+
+/**
+ * @brief Prints the ICMP echo reply messages.
+ *
+ * @return void
+ */
+void IcmpEchoData::print( const size_t &bytes_received,
+            const boost::posix_time::ptime &time_packet_sent,
+            const std::string &remote_address,
+            const uint32_t ttl) const
+{
+    boost::posix_time::ptime now
+                      = boost::posix_time::microsec_clock::universal_time();
+    time_resolution_traits_adapted64_impl::int_type elapsed_time =
+            (now - time_packet_sent).total_milliseconds();
+
+    GlobalLogger.info() << bytes_received << " bytes "
+         << "from " << remote_address
+         << ": icmp_seq=" << get_sequence_number()
+         << " ttl=" << ttl
+         << " time=" << elapsed_time << " ms" << std::endl;
+}
+
+std::string IcmpEchoData::to_string() const
+{
+    std::stringstream buf;
+    buf << "[EchoData ID=" << std::showbase << std::hex << get_identifier()
+        << ",seq.nr=" << std::noshowbase << std::dec<< get_sequence_number()
+        << ",data of size " << IcmpData::size-4;
+    //for (int idx=4; idx < IcmpData::size; ++idx)
+    //    buf << IcmpData::raw_data[idx];
+    buf << "]";
+    return buf.str();
+}
+
+// (created using vim -- the world's best text editor)
+
index 324b82c..e3be6eb 100644 (file)
 #include "icmp/icmpdata.h"
 
 #include <boost/date_time/posix_time/ptime.hpp>
-#include "boost/date_time/posix_time/posix_time_types.hpp"
-#include "boost/date_time/time_resolution_traits.hpp"
-#include <logfunc.hpp>
-
-using boost::date_time::time_resolution_traits_adapted64_impl;
-using I2n::Logger::GlobalLogger;
-
 /** @brief Data part of ICMP echo request and echo reply packets
  *
  * represents the last 4 bytes of the ICMP header (for v4) and the 8 bytes
@@ -44,35 +37,19 @@ class IcmpEchoData : public IcmpData
 {
 public:
     IcmpEchoData(const uint16_t identifier, const uint16_t sequence_number,
-                 const std::string &optional_data)
-        : IcmpData( 4 + optional_data.length() )
-    {
-        IcmpData::raw_data.encode16(0, 1, identifier);
-        IcmpData::raw_data.encode16(2, 3, sequence_number);
-        IcmpData::raw_data.encode_string(4, optional_data);
-        GlobalLogger.debug() << "Done creating echo request" << std::endl;
-    }
-
-    IcmpEchoData(const std::size_t size_arg)
-        : IcmpData( size_arg )
-    {}
+                 const std::string &optional_data);
+
+    IcmpEchoData(const std::size_t size_arg);
 
     bool match_destination_unreachable(const uint16_t identifier,
-                          const uint16_t sequence_number) const
-    { return false; }
+                          const uint16_t sequence_number) const;
 
     bool match_echo_reply(const uint16_t identifier,
-                          const uint16_t sequence_number) const
-    {
-        return get_identifier() == identifier
-            && get_sequence_number() == sequence_number;
-    };
+                          const uint16_t sequence_number) const;
 
-    uint16_t get_identifier() const
-    { return IcmpData::raw_data.decode16(0, 1);  }
+    uint16_t get_identifier() const;
 
-    uint16_t get_sequence_number() const
-    { return IcmpData::raw_data.decode16(2, 3);  }
+    uint16_t get_sequence_number() const;
 
     /**
      * @brief Prints the ICMP echo reply messages.
@@ -82,31 +59,9 @@ public:
     void print( const size_t &bytes_received,
                 const boost::posix_time::ptime &time_packet_sent,
                 const std::string &remote_address,
-                const uint32_t ttl) const
-    {
-        boost::posix_time::ptime now
-                          = boost::posix_time::microsec_clock::universal_time();
-        time_resolution_traits_adapted64_impl::int_type elapsed_time =
-                (now - time_packet_sent).total_milliseconds();
-
-        GlobalLogger.info() << bytes_received << " bytes "
-             << "from " << remote_address
-             << ": icmp_seq=" << get_sequence_number()
-             << " ttl=" << ttl
-             << " time=" << elapsed_time << " ms" << std::endl;
-    }
-
-    std::string to_string() const
-    {
-        std::stringstream buf;
-        buf << "[EchoData ID=" << std::showbase << std::hex << get_identifier()
-            << ",seq.nr=" << std::noshowbase << std::dec<< get_sequence_number()
-            << ",data of size " << IcmpData::size-4;
-        //for (int idx=4; idx < IcmpData::size; ++idx)
-        //    buf << IcmpData::raw_data[idx];
-        buf << "]";
-        return buf.str();
-    }
+                const uint32_t ttl) const;
+
+    std::string to_string() const;
 };
 
 #endif
index d8df8c7..0573ae2 100644 (file)
 #include <sstream>
 #include <boost/scoped_array.hpp>
 
+IcmpHeader::IcmpHeader()
+    : type( 0 )
+    , code( 0 )
+    , checksum( 0 )
+{}
+
+IcmpHeader::IcmpHeader(const uint8_t type_arg, const uint8_t code_arg)
+    : type( type_arg )
+    , code( code_arg )
+    , checksum( 0 )
+{}
+
+uint16_t IcmpHeader::get_header_length() const { return 4; }
+uint8_t  IcmpHeader::get_type()          const { return type; }
+uint8_t  IcmpHeader::get_code()          const { return code; }
+uint16_t IcmpHeader::get_checksum()      const { return checksum; }
+
+
 std::istream& IcmpHeader::read(std::istream &is)
 {
     boost::scoped_array<char> buf( new char[4] );
index e784ffd..2bf02ca 100644 (file)
 class IcmpHeader
 {
 public:
-    IcmpHeader()
-        : type( 0 )
-        , code( 0 )
-        , checksum( 0 )
-    {}
-
-    IcmpHeader(const uint8_t type_arg, const uint8_t code_arg)
-        : type( type_arg )
-        , code( code_arg )
-        , checksum( 0 )
-    {}
+    IcmpHeader();
+
+    IcmpHeader(const uint8_t type_arg, const uint8_t code_arg);
 
     std::istream& read(std::istream &is);
     std::ostream& write(std::ostream &os) const;
 
-    inline uint8_t get_type() const { return type; }
-    inline uint8_t get_code() const { return code; }
-    inline uint16_t get_checksum() const { return checksum; }
+    uint8_t get_type() const;
+    uint8_t get_code() const;
+    uint16_t get_checksum() const;
 
     void calc_checksum( const uint32_t body_checksum_part );
 
     // returns the amount of data represented by this class;
     // for Icmp v4, the header is actually 8 bytes, see comments above
-    inline uint16_t get_header_length() const
-    {    return 4;   }
+    uint16_t get_header_length() const;
 
     std::string to_string() const;
 
index 5862e65..37a776e 100644 (file)
 #include <logfunc.hpp>
 
 #include "boost_assert_handler.h"
+#include "ip/ipv4header.h"
+#include "ip/ipv6header.h"
 #include "icmp/icmpechodata.h"
 #include "icmp/icmpdestinationunreachabledata.h"
 
 
 using I2n::Logger::GlobalLogger;
 
+IcmpPacket::IcmpPacket(const icmp::socket::protocol_type &protocol)
+    : ip_head_ptr()
+    , icmp_header()
+    , icmp_data_ptr()
+{
+    if ( icmp::v4() == protocol )
+        ip_head_ptr.reset( new Ipv4Header() );
+    else if ( icmp::v6() == protocol )
+        ip_head_ptr.reset( new Ipv6Header() );
+    else  // pingcheck-type throwing of exceptions:
+        BOOST_ASSERT( !"Invalid IP version, need 4 or 6!" );
+}
+
+// IP header is created with only 0s, is not used in write, anyway
+IcmpPacket::IcmpPacket(const icmp::socket::protocol_type &protocol,
+           const IcmpHeader &icmp_header_arg,
+           const IcmpDataPtr &icmp_data_arg)
+    : ip_head_ptr()
+    , icmp_header( icmp_header_arg )
+    , icmp_data_ptr( icmp_data_arg )
+{
+    if ( icmp::v4() == protocol )
+        ip_head_ptr.reset( new Ipv4Header() );
+    else if ( icmp::v6() == protocol )
+        ip_head_ptr.reset( new Ipv6Header() );
+    else  // pingcheck-type throwing of exceptions:
+        BOOST_ASSERT( !"Invalid IP version, need 4 or 6!" );
+
+    // create checksum
+    icmp_header.calc_checksum( icmp_data_ptr->calc_checksum_part() );
+}
+
+// returns Icmpv4Type_InvalidLast if is actually v6 and not v4
+Icmpv4Type IcmpPacket::get_type_v4()
+{
+    if (ip_head_ptr->get_version() == 4)
+        return static_cast<Icmpv4Type>( icmp_header.get_type() );
+    else
+        return Icmpv4Type_InvalidLast;   // invalid
+}
+
+// returns Icmpv6Type_InvalidLast if is actually v4 and not v6
+Icmpv6Type IcmpPacket::get_type_v6()
+{
+    if (ip_head_ptr->get_version() == 6)
+        return static_cast<Icmpv6Type>( icmp_header.get_type() );
+    else
+        return Icmpv6Type_InvalidLast;   // invalid
+}
+
+
+bool IcmpPacket::check_integrity() { return false; } // not implemented yet
+
+bool IcmpPacket::match_destination_unreachable(const uint16_t identifier,
+                                   const uint16_t sequence_number,
+                                   const address &destination_address) const
+{
+    return ip_head_ptr->get_source_address() == destination_address
+       &&  icmp_data_ptr->match_destination_unreachable(identifier,
+                                                   sequence_number);
+}
+
+bool IcmpPacket::match_echo_reply(const uint16_t identifier,
+                      const uint16_t sequence_number,
+                      const address &destination_address) const
+{
+    return ip_head_ptr->get_source_address() == destination_address
+       &&  icmp_data_ptr->match_echo_reply(identifier, sequence_number);
+}
+
+/**
+ * @brief print echo reply / destination unreachable message depending on
+ *    ICMP data type
+ *
+ * @param bytes_transferred Number of bytes transferred.
+ * @param time_packet_sent The time when this packet was sent.
+ *
+ * @return void
+ */
+void IcmpPacket::print( const size_t &bytes_transferred,
+            const boost::posix_time::ptime &time_packet_sent    ) const
+{
+    size_t bytes_received = bytes_transferred
+                            - ip_head_ptr->get_header_length();
+    std::string remote_address
+                            = ip_head_ptr->get_source_address().to_string();
+    uint32_t ttl = ip_head_ptr->get_time_to_live();
+    icmp_data_ptr->print( bytes_received, time_packet_sent,
+                          remote_address, ttl);
+}
+
 /**
  * @brief Read (part of) the ICMP packet from the input stream @a is
  *
index 9e9aad1..f83ae5d 100644 (file)
@@ -32,8 +32,6 @@
 #include <boost/date_time/posix_time/ptime.hpp>
 
 #include "ip/ipheader.h"
-#include "ip/ipv4header.h"
-#include "ip/ipv6header.h"
 #include "icmp/icmpheader.h"
 #include "icmp/icmpdata.h"
 #include "icmp/icmptype.h"
@@ -63,73 +61,26 @@ public:
 
     static std::string return_code_to_string( const ReadReturnCode &code );
 
-    IcmpPacket(const icmp::socket::protocol_type &protocol)
-        : ip_head_ptr()
-        , icmp_header()
-        , icmp_data_ptr()
-    {
-        if ( icmp::v4() == protocol )
-            ip_head_ptr.reset( new Ipv4Header() );
-        else if ( icmp::v6() == protocol )
-            ip_head_ptr.reset( new Ipv6Header() );
-        else  // pingcheck-type throwing of exceptions:
-            BOOST_ASSERT( !"Invalid IP version, need 4 or 6!" );
-    }
+    IcmpPacket(const icmp::socket::protocol_type &protocol);
 
     // IP header is created with only 0s, is not used in write, anyway
     IcmpPacket(const icmp::socket::protocol_type &protocol,
                const IcmpHeader &icmp_header_arg,
-               const IcmpDataPtr &icmp_data_arg)
-        : ip_head_ptr()
-        , icmp_header( icmp_header_arg )
-        , icmp_data_ptr( icmp_data_arg )
-    {
-        if ( icmp::v4() == protocol )
-            ip_head_ptr.reset( new Ipv4Header() );
-        else if ( icmp::v6() == protocol )
-            ip_head_ptr.reset( new Ipv6Header() );
-        else  // pingcheck-type throwing of exceptions:
-            BOOST_ASSERT( !"Invalid IP version, need 4 or 6!" );
-
-        // create checksum
-        icmp_header.calc_checksum( icmp_data_ptr->calc_checksum_part() );
-    }
-
-    Icmpv4Type get_type_v4()
-    {
-        if (ip_head_ptr->get_version() == 4)
-            return static_cast<Icmpv4Type>( icmp_header.get_type() );
-        else
-            return Icmpv4Type_InvalidLast;   // invalid
-    }
-
-    Icmpv6Type get_type_v6()
-    {
-        if (ip_head_ptr->get_version() == 6)
-            return static_cast<Icmpv6Type>( icmp_header.get_type() );
-        else
-            return Icmpv6Type_InvalidLast;   // invalid
-    }
-
-
-    bool check_integrity() { return false; } // not implemented yet
-
-    bool match_destination_unreachable(const uint16_t identifier,
-                                       const uint16_t sequence_number,
-                                       const address &destination_address)
-    {
-        return ip_head_ptr->get_source_address() == destination_address
-           &&  icmp_data_ptr->match_destination_unreachable(identifier,
-                                                       sequence_number);
-    }
+               const IcmpDataPtr &icmp_data_arg);
+
+    Icmpv4Type get_type_v4();
+    Icmpv6Type get_type_v6();
+
+    bool check_integrity();   // not implemented yet
+
+    bool match_destination_unreachable(
+                          const uint16_t identifier,
+                          const uint16_t sequence_number,
+                          const address &destination_address) const;
 
     bool match_echo_reply(const uint16_t identifier,
                           const uint16_t sequence_number,
-                          const address &destination_address)
-    {
-        return ip_head_ptr->get_source_address() == destination_address
-           &&  icmp_data_ptr->match_echo_reply(identifier, sequence_number);
-    }
+                          const address &destination_address) const;
 
     /**
      * @brief print echo reply / destination unreachable message depending on
@@ -141,16 +92,7 @@ public:
      * @return void
      */
     void print( const size_t &bytes_transferred,
-                const boost::posix_time::ptime &time_packet_sent    ) const
-    {
-        size_t bytes_received = bytes_transferred
-                                - ip_head_ptr->get_header_length();
-        std::string remote_address
-                                = ip_head_ptr->get_source_address().to_string();
-        uint32_t ttl = ip_head_ptr->get_time_to_live();
-        icmp_data_ptr->print( bytes_received, time_packet_sent,
-                              remote_address, ttl);
-    }
+                const boost::posix_time::ptime &time_packet_sent    ) const;
 
     ReadReturnCode read(std::istream &is);
 
index 5b1de8c..b2697dd 100644 (file)
@@ -3,6 +3,8 @@ add_executable(test_icmpv4header
     test_icmpv4header.cpp
     ${CMAKE_SOURCE_DIR}/src/boost_assert_handler.cpp
     ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata.cpp
+    ${CMAKE_SOURCE_DIR}/src/icmp/icmpechodata.cpp
+    ${CMAKE_SOURCE_DIR}/src/icmp/icmpdestinationunreachabledata.cpp
     ${CMAKE_SOURCE_DIR}/src/icmp/icmpheader.cpp
     ${CMAKE_SOURCE_DIR}/src/host/messagepayload.cpp
 )
index e97478a..dcfeb34 100644 (file)
@@ -3,6 +3,8 @@ add_executable(test_icmpv6header
     test_icmpv6header.cpp
     ${CMAKE_SOURCE_DIR}/src/boost_assert_handler.cpp
     ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata.cpp
+    ${CMAKE_SOURCE_DIR}/src/icmp/icmpechodata.cpp
+    ${CMAKE_SOURCE_DIR}/src/icmp/icmpdestinationunreachabledata.cpp
     ${CMAKE_SOURCE_DIR}/src/icmp/icmpheader.cpp
     ${CMAKE_SOURCE_DIR}/src/host/messagepayload.cpp
 )