- Due to different fields, the printing methods were moved to the packet classes
     icmp/icmpv4header.cpp
     icmp/icmpmessage.cpp
     icmp/icmpv4packet.cpp
+    icmp/icmppacket.cpp
     icmp/icmppinger.cpp
     ip/ipv4header.cpp
     ip/ipv6header.cpp
 
--- /dev/null
+/*
+ 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.
+ */
+
+#include "icmp/icmppacket.h"
+
+//-----------------------------------------------------------------------------
+// IcmpPacket
+//-----------------------------------------------------------------------------
+
+IcmpPacket::IcmpPacket()
+{
+}
+
+IcmpPacket::~IcmpPacket()
+{
+}
+
 
--- /dev/null
+/*
+ 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.
+ */
+
+#ifndef ICMP_PACKET_H
+#define ICMP_PACKET_H
+
+#include <string>
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+//-----------------------------------------------------------------------------
+// IcmpPacket
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Abstract class for ICMP Packets.
+ */
+class IcmpPacket
+{
+public:
+    IcmpPacket();
+    virtual ~IcmpPacket();
+
+    virtual void print_echo_reply(
+            const std::size_t &bytes_transferred,
+            const boost::posix_time::ptime &time_packet_sent
+    ) const = 0;
+    virtual void print_destination_unreachable() const = 0;
+
+};
+
+#endif // ICMP_PACKET_H
 
 #include "icmp/icmpchecksum.h"
 #include "icmp/icmpdata.h"
 #include "icmp/icmpv4header.h"
-#include "icmp/icmpv4packet.h"
 #include "icmp/icmptype.h"
 #include "ip/ipv4header.h"
 
 using boost::asio::io_service;
 using boost::asio::ip::address;
 using boost::asio::ip::icmp;
-using boost::date_time::time_resolution_traits_adapted64_impl;
 using boost::function;
 using boost::posix_time::microsec_clock;
-using boost::posix_time::ptime;
 using boost::posix_time::seconds;
 using I2n::Logger::GlobalLogger;
 
         {
             ReceivedReply = true;
 
-            print_echo_reply( icmp_packet, bytes_transferred );
+            icmp_packet.print_echo_reply( bytes_transferred, TimeSent );
 
             set_ping_status( PingStatus_SuccessReply );
 
         {
             ReceivedReply = true;
 
-            print_destination_unreachable( icmp_packet );
+            icmp_packet.print_destination_unreachable();
 
             set_ping_status( PingStatus_FailureDestinationUnreachable );
 
     }
 }
 
-/**
- * @brief Prints the ICMP echo reply messages.
- *
- * @param icmp_packet The Icmpv4Packet object containing the received echo reply data.
- * @param bytes_transferred Number of bytes transferred.
- * @return void
- */
-void IcmpPinger::print_echo_reply(
-        const Icmpv4Packet &icmp_packet,
-        const size_t &bytes_transferred
-) const
-{
-    BOOST_ASSERT( icmp_packet.get_icmp_header().get_type() == Icmpv4Type_EchoReply );
-
-    Ipv4Header ipv4_header = icmp_packet.get_ip_header();
-    Icmpv4Header icmp_header = icmp_packet.get_icmp_header();
-
-    size_t bytes_received = bytes_transferred - ipv4_header.get_header_length();
-    string remote_address = ipv4_header.get_source_address().to_string();
-    uint16_t sequence_number = icmp_header.get_sequence_number();
-    int ttl = ipv4_header.get_time_to_live();
-    ptime now = microsec_clock::universal_time();
-    time_resolution_traits_adapted64_impl::int_type elapsed_time =
-            (now - TimeSent).total_milliseconds();
-
-    GlobalLogger.info() << bytes_received << " bytes "
-         << "from " << remote_address
-         << ": icmp_seq=" << sequence_number
-         << " ttl=" << ttl
-         << " time=" << elapsed_time << " ms" << endl;
-}
-
-/**
- * @brief Prints the destination unreachable messages.
- *
- * @param icmp_packet The Icmpv4Packet object containing the received destination
- * unreachable data.
- * @return void
- */
-void IcmpPinger::print_destination_unreachable(
-        const Icmpv4Packet &icmp_packet
-) const
-{
-    BOOST_ASSERT( icmp_packet.get_icmp_header().get_type() == Icmpv4Type_DestinationUnreachable );
-
-    Ipv4Header ipv4_hdr = icmp_packet.get_ip_header();
-    Icmpv4Header icmp_hdr = icmp_packet.get_icmp_header();
-
-    string local_address = ipv4_hdr.get_destination_address().to_string();
-    uint16_t sequence_number = icmp_hdr.get_sequence_number();
-
-    GlobalLogger.info() << "From " << local_address
-         << " icmp_seq=" << sequence_number
-         << " Destination Net Unreachable" << endl;
-}
-
 void IcmpPinger::set_ping_status( PingStatus ping_status )
 {
     PingerStatus = ping_status;
 
 #include "host/networkinterface.hpp"
 #include "host/pinger.h"
 #include "host/pingstatus.h"
+#include "icmp/icmpv4packet.h"
 
 class Icmpv4Packet;
 
     void start_receive();
     void handle_receive_icmp_packet( const std::size_t &bytes_transferred );
 
-    void print_echo_reply(
-            const Icmpv4Packet &icmp_packet,
-            const std::size_t &bytes_transferred
-    ) const;
-    void print_destination_unreachable(
-            const Icmpv4Packet &icmp_packet
-    ) const;
-
     void set_ping_status( PingStatus ping_status );
 
 private:
 
 
 #include <iostream>
 
+#include <logfunc.hpp>
+
 using namespace std;
 using boost::asio::ip::address;
+using boost::date_time::time_resolution_traits_adapted64_impl;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+using I2n::Logger::GlobalLogger;
 
 //-----------------------------------------------------------------------------
 // Icmpv4Packet
     return ( type_match && identifier_match && seq_num_match && address_match );
 }
 
+/**
+ * @brief Prints the ICMP echo reply messages.
+ *
+ * @param bytes_transferred Number of bytes transferred.
+ * @param time_packet_sent The time when this packet was sent.
+ *
+ * @return void
+ */
+void Icmpv4Packet::print_echo_reply(
+        const size_t &bytes_transferred,
+        const ptime &time_packet_sent
+) const
+{
+    BOOST_ASSERT( get_icmp_header().get_type() == Icmpv4Type_EchoReply );
+
+    Ipv4Header ipv4_header = get_ip_header();
+    Icmpv4Header icmpv4_header = get_icmp_header();
+
+    size_t bytes_received = bytes_transferred - ipv4_header.get_header_length();
+    string remote_address = ipv4_header.get_source_address().to_string();
+    uint16_t sequence_number = icmpv4_header.get_sequence_number();
+    int ttl = ipv4_header.get_time_to_live();
+    ptime now = 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=" << sequence_number
+         << " ttl=" << ttl
+         << " time=" << elapsed_time << " ms" << endl;
+}
+
+/**
+ * @brief Prints the destination unreachable messages.
+ *
+ * @return void
+ */
+void Icmpv4Packet::print_destination_unreachable() const
+{
+    BOOST_ASSERT( get_icmp_header().get_type() == Icmpv4Type_DestinationUnreachable );
+
+    Ipv4Header ipv4_hdr = get_ip_header();
+    Icmpv4Header icmpv4_hdr = get_icmp_header();
+
+    string local_address = ipv4_hdr.get_destination_address().to_string();
+    uint16_t sequence_number = icmpv4_hdr.get_sequence_number();
+
+    GlobalLogger.info() << "From " << local_address
+         << " icmp_seq=" << sequence_number
+         << " Destination Net Unreachable" << endl;
+}
+
 istream& operator>>(
         istream &is,
         Icmpv4Packet &packet
 
 
 #include <boost/asio.hpp>
 
+#include "icmp/icmppacket.h"
 #include "icmp/icmpv4header.h"
 #include "icmp/icmpdata.h"
 #include "icmp/icmptype.h"
  * +-------------------------------+------------------------------+      ---
  * @endcode
  */
-class Icmpv4Packet
+class Icmpv4Packet : public IcmpPacket
 {
 public:
     Icmpv4Packet();
             const boost::asio::ip::address &source_address
     ) const;
 
+    void print_echo_reply(
+            const std::size_t &bytes_transferred,
+            const boost::posix_time::ptime &time_packet_sent
+    ) const;
+    void print_destination_unreachable() const;
+
     friend std::istream& operator>>(
             std::istream &is,
             Icmpv4Packet &packet
 
 
 #include <iostream>
 
+#include <logfunc.hpp>
+
 using namespace std;
 using boost::asio::ip::address;
+using boost::date_time::time_resolution_traits_adapted64_impl;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+using I2n::Logger::GlobalLogger;
 
 //-----------------------------------------------------------------------------
 // Icmpv6Packet
     return ( type_match && identifier_match && seq_num_match && address_match );
 }
 
+/**
+ * @brief Prints the ICMP echo reply messages.
+ *
+ * @param bytes_transferred Number of bytes transferred.
+ * @param time_packet_sent The time when this packet was sent.
+ *
+ * @return void
+ */
+void Icmpv6Packet::print_echo_reply(
+        const size_t &bytes_transferred,
+        const ptime &time_packet_sent
+) const
+{
+    BOOST_ASSERT( get_icmp_header().get_type() == Icmpv6Type_EchoReply );
+
+    Ipv6Header ipv6_header = get_ip_header();
+    Icmpv6Header icmpv6_header = get_icmp_header();
+
+    size_t bytes_received = bytes_transferred - ipv6_header.get_payload_length();
+    string remote_address = ipv6_header.get_source_address().to_string();
+    uint16_t sequence_number = icmpv6_header.get_sequence_number();
+    int ttl = ipv6_header.get_hop_limit();
+    ptime now = 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=" << sequence_number
+         << " ttl=" << ttl
+         << " time=" << elapsed_time << " ms" << endl;
+}
+
+/**
+ * @brief Prints the destination unreachable messages.
+ *
+ * @return void
+ */
+void Icmpv6Packet::print_destination_unreachable() const
+{
+    BOOST_ASSERT( get_icmp_header().get_type() == Icmpv6Type_DestinationUnreachable );
+
+    Ipv6Header ipv6_hdr = get_ip_header();
+    Icmpv6Header icmpv6_hdr = get_icmp_header();
+
+    string local_address = ipv6_hdr.get_destination_address().to_string();
+    uint16_t sequence_number = icmpv6_hdr.get_sequence_number();
+
+    GlobalLogger.info() << "From " << local_address
+         << " icmp_seq=" << sequence_number
+         << " Destination Net Unreachable" << endl;
+}
+
 istream& operator>>(
         istream &is,
         Icmpv6Packet &packet
 
 
 #include <boost/asio.hpp>
 
+#include "icmp/icmppacket.h"
 #include "icmp/icmpv6header.h"
 #include "icmp/icmpdata.h"
 #include "icmp/icmptype.h"
  * +-------------------------------+------------------------------+      ---
  * @endcode
  */
-class Icmpv6Packet
+class Icmpv6Packet : public IcmpPacket
 {
 public:
     Icmpv6Packet();
             const boost::asio::ip::address &source_address
     ) const;
 
+    void print_echo_reply(
+            const std::size_t &bytes_transferred,
+            const boost::posix_time::ptime &time_packet_sent
+    ) const;
+    void print_destination_unreachable() const;
+
     friend std::istream& operator>>(
             std::istream &is,
             Icmpv6Packet &packet