re-ordered class for IcmpPacket
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 12 Mar 2015 10:04:43 +0000 (11:04 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 12 Mar 2015 10:04:43 +0000 (11:04 +0100)
old: IcmpPacket has and IpvXHeader, an IcmpvXHeader which varies according to ICMP message type and also contains part of Icmp message data, and an IcmpData which is a string;
new: IcmpPacket has an IpHeader, an IcmpHeader which represents only the common first 4 byte of ICMP v4/v6, and IcmpData which is either a IcmpEchoData for echo request/reply or a IcmpDestinationUnreachableData

tried to abstract away as much as possible (for a lay programmer like me) the difference between v4 and v6

This code now compiles, need to see whether it does anything usefull

Tests not compiled/run yet

27 files changed:
src/CMakeLists.txt
src/icmp/icmpdata.h
src/icmp/icmpdestinationunreachabledata.h [new file with mode: 0644]
src/icmp/icmpdestinationunreachablemessage.cpp [deleted file]
src/icmp/icmpdestinationunreachablemessage.h [deleted file]
src/icmp/icmpechodata.h [new file with mode: 0644]
src/icmp/icmpechoreplymessage.cpp [deleted file]
src/icmp/icmpechoreplymessage.h [deleted file]
src/icmp/icmpechorequestmessage.cpp [deleted file]
src/icmp/icmpechorequestmessage.h [deleted file]
src/icmp/icmpgenericmessage.cpp [deleted file]
src/icmp/icmpgenericmessage.h [deleted file]
src/icmp/icmpheader.h [new file with mode: 0644]
src/icmp/icmpmessage.cpp [deleted file]
src/icmp/icmpmessage.h [deleted file]
src/icmp/icmppacket.cpp
src/icmp/icmppacket.h
src/icmp/icmppacketfactory.cpp
src/icmp/icmppinger.cpp
src/icmp/icmpv4header.cpp [deleted file]
src/icmp/icmpv4header.h [deleted file]
src/icmp/icmpv4packet.cpp [deleted file]
src/icmp/icmpv4packet.h [deleted file]
src/icmp/icmpv6header.cpp [deleted file]
src/icmp/icmpv6header.h [deleted file]
src/icmp/icmpv6packet.cpp [deleted file]
src/icmp/icmpv6packet.h [deleted file]

index 11ecd07..9657ff3 100644 (file)
@@ -76,15 +76,6 @@ set(SOURCES
     host/pingprotocol.cpp
     host/pingrotate.cpp
     host/pingscheduler.cpp
-    icmp/icmpdestinationunreachablemessage.cpp
-    icmp/icmpechoreplymessage.cpp
-    icmp/icmpechorequestmessage.cpp
-    icmp/icmpgenericmessage.cpp
-    icmp/icmpv4header.cpp
-    icmp/icmpv6header.cpp
-    icmp/icmpmessage.cpp
-    icmp/icmpv4packet.cpp
-    icmp/icmpv6packet.cpp
     icmp/icmppacket.cpp
     icmp/icmppinger.cpp
     icmp/icmppacketfactory.cpp
index cda6140..dcb8586 100644 (file)
@@ -1,18 +1,89 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
+/*
+ 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
+ */
+
 #ifndef ICMP_DATA_H
 #define ICMP_DATA_H
 
-#include <string>
+#include <stdint.h>
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+#include <boost/date_time/posix_time/ptime.hpp>
+#include "host/messagepayload.h"
+
+/** @brief contents of ICMP packets after the first 4 bytes of the ICMP header
+ * used for ICMPv4 and ICMPv6
+ *
+ * subclasses only have to specify which part of raw_data to access for which
+ *   information
+ */
+class IcmpData
+{
+public:
+    IcmpData()
+        : size( 0 )
+        , raw_data( 0 )
+    {}
+
+    virtual bool match_echo_reply(const uint16_t identifier,
+                                  const uint16_t sequence_number) const
+    {  return false;  };
+
+    virtual bool match_destination_unreachable(const uint16_t identifier,
+                                  const uint16_t sequence_number) const
+    {  return false;  };
+
+    std::size_t get_size() { return size; };
+
+    virtual std::istream& read(std::istream &is)  // read raw data
+    { return raw_data.read(is);  }
+
+    std::ostream& write(std::ostream &os)
+    { return raw_data.write(os); }
+
+    virtual ~IcmpData() {}
+
+    uint32_t calc_checksum_part() const
+    {   return raw_data.calc_checksum_part();  }
+
+    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
+    {}
+
+protected:
+
+    IcmpData(const std::size_t size_arg)
+        : size( size_arg )
+        , raw_data( size_arg )
+    {}
+
+    std::size_t size;
+    MessagePayload raw_data;
+};
+
+typedef boost::shared_ptr<IcmpData> IcmpDataPtr;
 
-//-----------------------------------------------------------------------------
-// IcmpData
-//-----------------------------------------------------------------------------
+#endif
 
-typedef std::string IcmpData;
+// (created using vim -- the world's best text editor)
 
-#endif // ICMP_DATA_H
diff --git a/src/icmp/icmpdestinationunreachabledata.h b/src/icmp/icmpdestinationunreachabledata.h
new file mode 100644 (file)
index 0000000..de375fd
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ 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
+ */
+
+
+#ifndef ICMP_DEST_11_H
+#define ICMP_DEST_11_H
+
+#include <stdint.h>
+#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):
+ * +---------------------------+
+ * |      reply IP header      | 20/40 bytes --> not contained in here
+ * +---------------------------+
+ * |     reply ICMP header:    |
+ * | type | code |  checksum   |  4 byte --> not contained in here !
+ * |   4 uninteresting bytes   |  4 byte --> contained in here!
+ * +---------------------------+
+ * |           request         | 20 / 40 bytes
+ * |          IP header        | for IP v4 / v6 
+ * +---------------------------+
+ * |    request ICMP packet:   |
+ * | type | code |  checksum   |  1+1+2 byte
+ * |  identifier | seq. number |  2+2 byte
+ * |           data            |  4 byte
+ * |           data            |  4 byte
+ * +---------------------------+
+ * (where "in here" means in variable raw_data of class 
+ *  IcmpDestinationUnreachableData)
+ *
+ * see also: https://tools.ietf.org/html/rfc792 (ICMP v4)
+ *           https://tools.ietf.org/html/rfc4443 (ICMP v6)
+ */
+
+/**
+ * contains the request IP and ICMP header and possibly more data from request
+ */
+class IcmpDestinationUnreachableData : public IcmpData
+{
+public:
+    IcmpDestinationUnreachableData(const std::size_t size_arg)
+        : IcmpData( size_arg )
+    {}
+
+    bool match_echo_reply(const uint16_t identifier,
+                          const uint16_t sequence_number) const
+    { return false; }
+
+    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
+            IcmpData::raw_data.decode16(offset+data_offset,
+                                        offset+data_offset+1);
+    }
+
+    /**
+     * @brief Prints the destination unreachable messages.
+     *
+     * @return void
+     */
+    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;
+    }
+
+
+
+};
+
+#endif
+
+// (created using vim -- the world's best text editor)
+
diff --git a/src/icmp/icmpdestinationunreachablemessage.cpp b/src/icmp/icmpdestinationunreachablemessage.cpp
deleted file mode 100644 (file)
index ac3e0e6..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpdestinationunreachablemessage.h"
-
-#include <cstddef>
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-// IcmpDestinationUnreachableMessage
-//-----------------------------------------------------------------------------
-
-static const size_t MessageSizeInBytes = 44;
-
-IcmpDestinationUnreachableMessage::IcmpDestinationUnreachableMessage() :
-    Payload( MessageSizeInBytes )
-{
-}
-
-IcmpDestinationUnreachableMessage::~IcmpDestinationUnreachableMessage()
-{
-}
-
-Icmpv4Type IcmpDestinationUnreachableMessage::get_type_v4() const
-{
-    Icmpv4Type type = static_cast<Icmpv4Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpDestinationUnreachableMessage::set_type_v4( const Icmpv4Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-Icmpv6Type IcmpDestinationUnreachableMessage::get_type_v6() const
-{
-    Icmpv6Type type = static_cast<Icmpv6Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpDestinationUnreachableMessage::set_type_v6( const Icmpv6Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-uint8_t IcmpDestinationUnreachableMessage::get_code() const
-{
-    return Payload[ 1 ];
-}
-
-void IcmpDestinationUnreachableMessage::set_code( uint8_t code )
-{
-    Payload[ 1 ] = code;
-}
-
-uint16_t IcmpDestinationUnreachableMessage::get_checksum() const
-{
-    return Payload.decode16( 2, 3 );
-}
-
-void IcmpDestinationUnreachableMessage::set_checksum( uint16_t checksum )
-{
-    Payload.encode16( 2, 3, checksum );
-}
-
-uint16_t IcmpDestinationUnreachableMessage::get_identifier() const
-{
-    return Payload.decode16( 32, 33 );
-}
-
-void IcmpDestinationUnreachableMessage::set_identifier(
-        const uint16_t identifier
-)
-{
-    Payload.encode16( 32, 33, identifier );
-}
-
-uint16_t IcmpDestinationUnreachableMessage::get_sequence_number() const
-{
-    return Payload.decode16( 34, 35 );
-}
-
-void IcmpDestinationUnreachableMessage::set_sequence_number(
-        const uint16_t sequence_number
-)
-{
-    Payload.encode16( 34, 35, sequence_number );
-}
-
-std::istream& IcmpDestinationUnreachableMessage::read( std::istream &is )
-{
-    return Payload.read( is );
-}
-
-std::ostream& IcmpDestinationUnreachableMessage::write(
-        std::ostream &os
-) const
-{
-    return Payload.write( os );
-}
diff --git a/src/icmp/icmpdestinationunreachablemessage.h b/src/icmp/icmpdestinationunreachablemessage.h
deleted file mode 100644 (file)
index 387d68e..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMP_DESTINATION_UNREACHABLE_MESSAGE_H
-#define ICMP_DESTINATION_UNREACHABLE_MESSAGE_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include "icmp/icmpmessage.h"
-#include "host/messagepayload.h"
-
-//-----------------------------------------------------------------------------
-// IcmpDestinationUnreachableMessage
-//-----------------------------------------------------------------------------
-//
-// ICMP Destination Unreachable Message Format
-
-// 0               8               16                             31
-// +---------------+---------------+------------------------------+      ---
-// |               |               |                              |       ^
-// |     type      |     code      |          checksum            |       |
-// |               |               |                              |       |
-// +---------------+---------------+------------------------------+    8 bytes
-// |                                                              |       |
-// |                            unused                            |       |
-// |                                                              |       v
-// +-------------------------------+------------------------------+      ---
-// |                                                              |       ^
-// |                   Internet Protocol (IP) Header              |   20 bytes
-// |                                                              |       v
-// +-------------------------------+------------------------------+      ---
-// |                                                              |       ^
-// |                    Original ICMP Data Datagram               |   20 bytes
-// |                                                              |       v
-// +-------------------------------+------------------------------+      ---
-//
-//-----------------------------------------------------------------------------
-
-class IcmpDestinationUnreachableMessage : public IcmpMessage
-{
-public:
-    IcmpDestinationUnreachableMessage();
-    virtual ~IcmpDestinationUnreachableMessage();
-
-    virtual Icmpv4Type get_type_v4() const;
-    virtual void set_type_v4( const Icmpv4Type type );
-
-    virtual Icmpv6Type get_type_v6() const;
-    virtual void set_type_v6( const Icmpv6Type type );
-
-    virtual uint8_t get_code() const;
-    virtual void set_code( const uint8_t code );
-
-    virtual uint16_t get_checksum() const;
-    virtual void set_checksum( const uint16_t checksum );
-
-    virtual uint16_t get_identifier() const;
-    virtual void set_identifier( const uint16_t identifier );
-
-    virtual uint16_t get_sequence_number() const;
-    virtual void set_sequence_number( const uint16_t sequence_number );
-
-    virtual std::istream& read( std::istream &is );
-    virtual std::ostream& write( std::ostream &os ) const;
-
-private:
-    /// packet payload object
-    MessagePayload Payload;
-
-};
-
-#endif // ICMP_DESTINATION_UNREACHABLE_MESSAGE_H
diff --git a/src/icmp/icmpechodata.h b/src/icmp/icmpechodata.h
new file mode 100644 (file)
index 0000000..ae31517
--- /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
+ */
+
+#ifndef ICMP_ECHO_DATA_H
+#define ICMP_ECHO_DATA_H
+
+#include <stdint.h>
+#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
+ *   of optional data; for v6 this (same amount of?!) data is defined as the
+ *   body
+ */
+class IcmpEchoData : public IcmpData
+{
+public:
+    IcmpEchoData(const uint16_t identifier, const uint16_t sequence_number,
+                 const std::string &optional_data)
+        : IcmpData(12)
+    {
+        IcmpData::raw_data.encode16(0, 1, identifier);
+        IcmpData::raw_data.encode16(2, 3, sequence_number);
+        IcmpData::raw_data.encode_string(4, optional_data);
+    }
+
+    IcmpEchoData(const std::size_t size_arg)
+        : IcmpData( size_arg )
+    {}
+
+    bool match_destination_unreachable(const uint16_t identifier,
+                          const uint16_t sequence_number) const
+    { return false; }
+
+    bool match_echo_reply(const uint16_t identifier,
+                          const uint16_t sequence_number) const
+    {
+        return get_identifier() == identifier
+            && get_sequence_number() == sequence_number;
+    };
+
+    uint16_t get_identifier() const
+    { return IcmpData::raw_data.decode16(0, 1);  }
+
+    uint16_t get_sequence_number() const
+    { return IcmpData::raw_data.decode16(2, 3);  }
+
+    /**
+     * @brief Prints the ICMP echo reply messages.
+     *
+     * @return void
+     */
+    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;
+    }
+
+};
+
+#endif
+
+// (created using vim -- the world's best text editor)
+
diff --git a/src/icmp/icmpechoreplymessage.cpp b/src/icmp/icmpechoreplymessage.cpp
deleted file mode 100644 (file)
index 19719c8..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpechoreplymessage.h"
-
-#include <cstddef>
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-// IcmpEchoReplyMessage
-//-----------------------------------------------------------------------------
-
-static const size_t MessageSizeInBytes = 8;
-
-IcmpEchoReplyMessage::IcmpEchoReplyMessage() :
-    Payload( MessageSizeInBytes )
-{
-}
-
-IcmpEchoReplyMessage::~IcmpEchoReplyMessage()
-{
-}
-
-Icmpv4Type IcmpEchoReplyMessage::get_type_v4() const
-{
-    Icmpv4Type type = static_cast<Icmpv4Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpEchoReplyMessage::set_type_v4( const Icmpv4Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-Icmpv6Type IcmpEchoReplyMessage::get_type_v6() const
-{
-    Icmpv6Type type = static_cast<Icmpv6Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpEchoReplyMessage::set_type_v6( const Icmpv6Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-uint8_t IcmpEchoReplyMessage::get_code() const
-{
-    return Payload[ 1 ];
-}
-
-void IcmpEchoReplyMessage::set_code( uint8_t code )
-{
-    Payload[ 1 ] = code;
-}
-
-uint16_t IcmpEchoReplyMessage::get_checksum() const
-{
-    return Payload.decode16( 2, 3 );
-}
-
-void IcmpEchoReplyMessage::set_checksum( uint16_t checksum )
-{
-    Payload.encode16( 2, 3, checksum );
-}
-
-uint16_t IcmpEchoReplyMessage::get_identifier() const
-{
-    return Payload.decode16( 4, 5 );
-}
-
-void IcmpEchoReplyMessage::set_identifier(
-        const uint16_t identifier
-)
-{
-    Payload.encode16( 4, 5, identifier );
-}
-
-uint16_t IcmpEchoReplyMessage::get_sequence_number() const
-{
-    return Payload.decode16( 6, 7 );
-}
-
-void IcmpEchoReplyMessage::set_sequence_number(
-        const uint16_t sequence_number
-)
-{
-    Payload.encode16( 6, 7, sequence_number );
-}
-
-std::istream& IcmpEchoReplyMessage::read( std::istream &is )
-{
-    return Payload.read( is );
-}
-
-std::ostream& IcmpEchoReplyMessage::write( std::ostream &os ) const
-{
-    return Payload.write( os );
-}
diff --git a/src/icmp/icmpechoreplymessage.h b/src/icmp/icmpechoreplymessage.h
deleted file mode 100644 (file)
index 32016d6..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMP_ECHO_REPLY_MESSAGE_H
-#define ICMP_ECHO_REPLY_MESSAGE_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include "icmp/icmpmessage.h"
-#include "host/messagepayload.h"
-
-//-----------------------------------------------------------------------------
-// IcmpEchoReplyMessage
-//-----------------------------------------------------------------------------
-//
-// ICMP Echo Reply Message Format
-//
-// 0               8               16                             31
-// +---------------+---------------+------------------------------+      ---
-// |               |               |                              |       ^
-// |     type      |     code      |          checksum            |       |
-// |               |               |                              |       |
-// +---------------+---------------+------------------------------+    8 bytes
-// |                               |                              |       |
-// |          identifier           |       sequence number        |       |
-// |                               |                              |       v
-// +-------------------------------+------------------------------+      ---
-// |                                                              |
-// |                           data (n bytes)                     |
-// |                                                              |
-// +-------------------------------+------------------------------+
-//
-//-----------------------------------------------------------------------------
-
-class IcmpEchoReplyMessage : public IcmpMessage
-{
-public:
-    IcmpEchoReplyMessage();
-    virtual ~IcmpEchoReplyMessage();
-
-    virtual Icmpv4Type get_type_v4() const;
-    virtual void set_type_v4( const Icmpv4Type type );
-
-    virtual Icmpv6Type get_type_v6() const;
-    virtual void set_type_v6( const Icmpv6Type type );
-
-    virtual uint8_t get_code() const;
-    virtual void set_code( const uint8_t code );
-
-    virtual uint16_t get_checksum() const;
-    virtual void set_checksum( const uint16_t checksum );
-
-    virtual uint16_t get_identifier() const;
-    virtual void set_identifier( const uint16_t identifier );
-
-    virtual uint16_t get_sequence_number() const;
-    virtual void set_sequence_number( const uint16_t sequence_number );
-
-    virtual std::istream& read( std::istream &is );
-    virtual std::ostream& write( std::ostream &os ) const;
-
-private:
-    /// packet payload object
-    MessagePayload Payload;
-
-};
-
-#endif // ICMP_ECHO_REPLY_MESSAGE_H
diff --git a/src/icmp/icmpechorequestmessage.cpp b/src/icmp/icmpechorequestmessage.cpp
deleted file mode 100644 (file)
index 28bf382..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpechorequestmessage.h"
-
-#include <cstddef>
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-// IcmpEchoRequestMessage
-//-----------------------------------------------------------------------------
-
-static const size_t MessageSizeInBytes = 8;
-
-IcmpEchoRequestMessage::IcmpEchoRequestMessage() :
-    Payload( MessageSizeInBytes )
-{
-}
-
-IcmpEchoRequestMessage::~IcmpEchoRequestMessage()
-{
-}
-
-Icmpv4Type IcmpEchoRequestMessage::get_type_v4() const
-{
-    Icmpv4Type type = static_cast<Icmpv4Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpEchoRequestMessage::set_type_v4( const Icmpv4Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-Icmpv6Type IcmpEchoRequestMessage::get_type_v6() const
-{
-    Icmpv6Type type = static_cast<Icmpv6Type>( Payload[ 0 ] );
-
-    return type;
-}
-
-void IcmpEchoRequestMessage::set_type_v6( const Icmpv6Type type )
-{
-    uint8_t n = static_cast<uint8_t>( type );
-
-    Payload[ 0 ] = n;
-}
-
-uint8_t IcmpEchoRequestMessage::get_code() const
-{
-    return Payload[ 1 ];
-}
-
-void IcmpEchoRequestMessage::set_code( uint8_t code )
-{
-    Payload[ 1 ] = code;
-}
-
-uint16_t IcmpEchoRequestMessage::get_checksum() const
-{
-    return Payload.decode16( 2, 3 );
-}
-
-void IcmpEchoRequestMessage::set_checksum( uint16_t checksum )
-{
-    Payload.encode16( 2, 3, checksum );
-}
-
-uint16_t IcmpEchoRequestMessage::get_identifier() const
-{
-    return Payload.decode16( 4, 5 );
-}
-
-void IcmpEchoRequestMessage::set_identifier(
-        const uint16_t identifier
-)
-{
-    Payload.encode16( 4, 5, identifier );
-}
-
-uint16_t IcmpEchoRequestMessage::get_sequence_number() const
-{
-    return Payload.decode16( 6, 7 );
-}
-
-void IcmpEchoRequestMessage::set_sequence_number(
-        const uint16_t sequence_number
-)
-{
-    Payload.encode16( 6, 7, sequence_number );
-}
-
-std::istream& IcmpEchoRequestMessage::read( std::istream &is )
-{
-    return Payload.read( is );
-}
-
-std::ostream& IcmpEchoRequestMessage::write( std::ostream &os ) const
-{
-    return Payload.write( os );
-}
diff --git a/src/icmp/icmpechorequestmessage.h b/src/icmp/icmpechorequestmessage.h
deleted file mode 100644 (file)
index 246562c..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMP_ECHO_REQUEST_MESSAGE_H
-#define ICMP_ECHO_REQUEST_MESSAGE_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include "icmp/icmpmessage.h"
-#include "host/messagepayload.h"
-
-//-----------------------------------------------------------------------------
-// IcmpEchoRequestMessage
-//-----------------------------------------------------------------------------
-//
-// ICMP Echo Request Message Format
-//
-// 0               8               16                             31
-// +---------------+---------------+------------------------------+      ---
-// |               |               |                              |       ^
-// |     type      |     code      |          checksum            |       |
-// |               |               |                              |       |
-// +---------------+---------------+------------------------------+    8 bytes
-// |                               |                              |       |
-// |          identifier           |       sequence number        |       |
-// |                               |                              |       v
-// +-------------------------------+------------------------------+      ---
-// |                                                              |
-// |                           data (n bytes)                     |
-// |                                                              |
-// +-------------------------------+------------------------------+
-//
-//-----------------------------------------------------------------------------
-
-class IcmpEchoRequestMessage : public IcmpMessage
-{
-public:
-    IcmpEchoRequestMessage();
-    virtual ~IcmpEchoRequestMessage();
-
-    virtual Icmpv4Type get_type_v4() const;
-    virtual void set_type_v4( const Icmpv4Type type );
-
-    virtual Icmpv6Type get_type_v6() const;
-    virtual void set_type_v6( const Icmpv6Type type );
-
-    virtual uint8_t get_code() const;
-    virtual void set_code( const uint8_t code );
-
-    virtual uint16_t get_checksum() const;
-    virtual void set_checksum( const uint16_t checksum );
-
-    virtual uint16_t get_identifier() const;
-    virtual void set_identifier( const uint16_t identifier );
-
-    virtual uint16_t get_sequence_number() const;
-    virtual void set_sequence_number( const uint16_t sequence_number );
-
-    virtual std::istream& read( std::istream &is );
-    virtual std::ostream& write( std::ostream &os ) const;
-
-private:
-    /// packet payload object
-    MessagePayload Payload;
-
-};
-
-#endif // ICMP_ECHO_REQUEST_MESSAGE_H
diff --git a/src/icmp/icmpgenericmessage.cpp b/src/icmp/icmpgenericmessage.cpp
deleted file mode 100644 (file)
index 1bbee87..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpgenericmessage.h"
-
-//-----------------------------------------------------------------------------
-// IcmpGenericMessage
-//-----------------------------------------------------------------------------
-
-IcmpGenericMessage::IcmpGenericMessage()
-{
-}
-
-IcmpGenericMessage::~IcmpGenericMessage()
-{
-}
-
-Icmpv4Type IcmpGenericMessage::get_type_v4() const
-{
-    return Icmpv4Type_Generic;
-}
-
-void IcmpGenericMessage::set_type_v4( const Icmpv4Type )
-{
-}
-
-Icmpv6Type IcmpGenericMessage::get_type_v6() const
-{
-    return Icmpv6Type_Generic;
-}
-
-void IcmpGenericMessage::set_type_v6( const Icmpv6Type )
-{
-}
-
-uint8_t IcmpGenericMessage::get_code() const
-{
-    return 0;
-}
-
-void IcmpGenericMessage::set_code( uint8_t )
-{
-}
-
-uint16_t IcmpGenericMessage::get_checksum() const
-{
-    return 0;
-}
-
-void IcmpGenericMessage::set_checksum( uint16_t )
-{
-}
-
-uint16_t IcmpGenericMessage::get_identifier() const
-{
-    return 0;
-}
-
-void IcmpGenericMessage::set_identifier( uint16_t )
-{
-}
-
-uint16_t IcmpGenericMessage::get_sequence_number() const
-{
-    return 0;
-}
-
-void IcmpGenericMessage::set_sequence_number( uint16_t )
-{
-}
-
-std::istream& IcmpGenericMessage::read( std::istream &is )
-{
-    return is;
-}
-
-std::ostream& IcmpGenericMessage::write( std::ostream &os ) const
-{
-    return os;
-}
diff --git a/src/icmp/icmpgenericmessage.h b/src/icmp/icmpgenericmessage.h
deleted file mode 100644 (file)
index 3404dc0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMP_GENERIC_MESSAGE_H
-#define ICMP_GENERIC_MESSAGE_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include "icmp/icmpmessage.h"
-
-//-----------------------------------------------------------------------------
-// IcmpGenericMessage
-//-----------------------------------------------------------------------------
-
-/**
- * This class intends to handle ICMP messages that the application do not
- * want to read. It acts like a stub.
- */
-class IcmpGenericMessage : public IcmpMessage
-{
-public:
-    IcmpGenericMessage();
-    virtual ~IcmpGenericMessage();
-
-    virtual Icmpv4Type get_type_v4() const;
-    virtual void set_type_v4( const Icmpv4Type type );
-
-    virtual Icmpv6Type get_type_v6() const;
-    virtual void set_type_v6( const Icmpv6Type type );
-
-    virtual uint8_t get_code() const;
-    virtual void set_code( const uint8_t code );
-
-    virtual uint16_t get_checksum() const;
-    virtual void set_checksum( const uint16_t checksum );
-
-    virtual uint16_t get_identifier() const;
-    virtual void set_identifier( const uint16_t identifier );
-
-    virtual uint16_t get_sequence_number() const;
-    virtual void set_sequence_number( const uint16_t sequence_number );
-
-    virtual std::istream& read( std::istream &is );
-    virtual std::ostream& write( std::ostream &os ) const;
-
-};
-
-#endif // ICMP_GENERIC_MESSAGE_H
diff --git a/src/icmp/icmpheader.h b/src/icmp/icmpheader.h
new file mode 100644 (file)
index 0000000..b9922d9
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ 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
+ */
+
+#ifndef ICMP_HEADER_H
+#define ICMP_HEADER_H
+
+#include <stdint.h>
+#include <iostream>
+#include <boost/scoped_array.hpp>
+
+/** @brief first 4 byte of ICMP header (v4 and v6)
+ *
+ * In ICMP v4, the first 4 bytes are standardized, the other 4 depend on
+ *   message type. In Icmp v6, the header IS only the first 4 bytes.
+ * So everything after those first 4 bytes is contained in IcmpData subclasses
+ */
+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 )
+    {}
+
+    std::istream& read(std::istream &is)
+    {
+        boost::scoped_array<char> buf( new char[4] );
+        is.read(buf.get(), 4);
+        type = static_cast<uint8_t>(buf[0]);
+        code = static_cast<uint8_t>(buf[1]);
+        checksum = ( static_cast<uint16_t>(buf[2]) << 8 )
+                   + static_cast<uint16_t>(buf[3]);
+
+        return is;
+    }
+
+    uint8_t get_type() const { return type; }
+    uint8_t get_code() const { return code; }
+    uint16_t get_checksum() const { return checksum; }
+
+    // code adapted from boost icmp example by Christopher M. Kohlhoff
+    // --> boost license?!?
+    void calc_checksum( const uint32_t body_checksum_part )
+    {
+        uint32_t sum = (type << 8) + code;
+        sum += body_checksum_part;
+
+        sum = (sum >> 16) + (sum & 0xFFFF);
+        sum += (sum >> 16);
+
+        checksum = static_cast<uint16_t>( ~sum );
+    }
+
+    bool write(std::ostream &os) const
+    {
+        os << type << code << checksum;
+        return os.good();
+    }
+
+    // returns the amount of data represented by this class;
+    // for Icmp v4, the header is actually 8 bytes, see comments above
+    uint16_t get_header_length() const
+    {    return 4;   }
+
+protected:
+    uint8_t type;
+    uint8_t code;
+    uint16_t checksum;   // to be used in check_integrity
+};
+
+
+#endif
+
+// (created using vim -- the world's best text editor)
+
diff --git a/src/icmp/icmpmessage.cpp b/src/icmp/icmpmessage.cpp
deleted file mode 100644 (file)
index cffff70..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpmessage.h"
-
-//-----------------------------------------------------------------------------
-// IcmpMessage
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Default constructor.
- */
-IcmpMessage::IcmpMessage()
-{
-}
-
-/**
- * @brief Destructor.
- */
-IcmpMessage::~IcmpMessage()
-{
-}
-
-/**
- * This method MUST be called to initialize the data member of ICMP Messages.
- */
-void IcmpMessage::init( const Icmpv4Type type )
-{
-    // Note: this code can not be placed in the constructor, because it calls
-    // virtual function. If you call virtual functions from within a
-    // constructor, the Base class version of methods will be called, not the
-    // Derived class, because the Base is constructed before the Derived class.
-    set_type_v4( type );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
-
-/**
- * This method MUST be called to initialize the data member of ICMP Messages.
- */
-void IcmpMessage::init( const Icmpv6Type type )
-{
-    // Note: this code can not be placed in the constructor, because it calls
-    // virtual function. If you call virtual functions from within a
-    // constructor, the Base class version of methods will be called, not the
-    // Derived class, because the Base is constructed before the Derived class.
-    set_type_v6( type );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
diff --git a/src/icmp/icmpmessage.h b/src/icmp/icmpmessage.h
deleted file mode 100644 (file)
index 60ae871..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMP_MESSAGE_H
-#define ICMP_MESSAGE_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-#include <boost/utility.hpp>
-
-#include "icmp/icmptype.h"
-
-//-----------------------------------------------------------------------------
-// IcmpMessage
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Abstract class to which the ICMP messages are interpreted.
- */
-class IcmpMessage : boost::noncopyable
-{
-public:
-    void init( const Icmpv4Type type );
-    void init( const Icmpv6Type type );
-
-    virtual Icmpv4Type get_type_v4() const = 0;
-    virtual void set_type_v4( const Icmpv4Type type ) = 0;
-
-    virtual Icmpv6Type get_type_v6() const = 0;
-    virtual void set_type_v6( const Icmpv6Type type ) = 0;
-
-    virtual uint8_t get_code() const = 0;
-    virtual void set_code( const uint8_t code ) = 0;
-
-    virtual uint16_t get_checksum() const = 0;
-    virtual void set_checksum( const uint16_t checksum ) = 0;
-
-    virtual uint16_t get_identifier() const = 0;
-    virtual void set_identifier( const uint16_t identifier ) = 0;
-
-    virtual uint16_t get_sequence_number() const = 0;
-    virtual void set_sequence_number( const uint16_t sequence_number ) = 0;
-
-    virtual std::istream& read( std::istream &is ) = 0;
-    virtual std::ostream& write( std::ostream &os ) const = 0;
-
-protected:
-    IcmpMessage();
-    virtual ~IcmpMessage();
-
-};
-
-#endif // ICMP_MESSAGE_H
index c012ec9..f92bdec 100644 (file)
 
  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/icmppacket.h"
+
 #include <iostream>
+#include <boost/scoped_array.hpp>
 
-//-----------------------------------------------------------------------------
-// IcmpPacket
-//-----------------------------------------------------------------------------
+#include <logfunc.hpp>
 
-/**
- * @brief Default constructor.
- */
-IcmpPacket::IcmpPacket()
-{
-}
+#include "boost_assert_handler.h"
+#include "icmp/icmpechodata.h"
+#include "icmp/icmpdestinationunreachabledata.h"
+
+
+using I2n::Logger::GlobalLogger;
 
 /**
- * @brief Destructor.
+ * @brief Read (part of) the ICMP packet from the input stream @a is
+ *
+ * @param is The input stream.
+ *
+ * @return result of the read, currently one of {ok, fail, not enough data}
  */
-IcmpPacket::~IcmpPacket()
+IcmpPacket::ReadReturnCode IcmpPacket::read( std::istream &is )
 {
+    if ( !is.good() )
+        return IcmpPacket::ReadReturnCode_BAD_STREAM;
+
+    // try to read ip header
+    uint8_t version = static_cast<uint8_t>( is.peek() );
+    if (version == 4)
+    {
+        Ipv4Header *new_header = new Ipv4Header();
+        is >> *new_header;
+        ip_head_ptr.reset( new_header );
+    }
+    else if (version == 6)
+    {
+        Ipv6Header *new_header = new Ipv6Header();
+        is >> *new_header;
+        ip_head_ptr.reset( new_header );
+    }
+    else    // pingcheck-type error throwing
+        BOOST_ASSERT( !"Invalid IP version!" );
+
+    if ( is.eof() )
+        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
+    else if ( !is.good() )
+        return IcmpPacket::ReadReturnCode_BAD_STREAM;
+
+    // try to read the icmp header
+    icmp_header.read(is);
+
+    if ( is.eof() )
+        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
+    else if ( !is.good() )
+        return IcmpPacket::ReadReturnCode_BAD_STREAM;
+
+    // calculate the size of the ICMP data
+    std::streamsize data_length = static_cast<std::streamsize>( ip_head_ptr->get_total_length() )
+                                - static_cast<std::streamsize>( ip_head_ptr->get_header_length() )
+                                - static_cast<std::streamsize>( icmp_header.get_header_length() );
+
+    // try to read that amount of data
+    if ( data_length < 0 )
+    {
+        GlobalLogger.error() << "Invalid size for optional ICMP data: "
+                             << data_length << std::endl;
+        is.setstate( std::ios::failbit );
+        return IcmpPacket::ReadReturnCode_INVALID_SIZE;
+    }
+    else if ( data_length > 0 )
+    {
+        if (   get_type_v4() == Icmpv4Type_EchoRequest
+            || get_type_v4() == Icmpv4Type_EchoReply
+            || get_type_v6() == Icmpv6Type_EchoRequest
+            || get_type_v6() == Icmpv6Type_EchoReply  )
+            icmp_data_ptr.reset( new IcmpEchoData(
+                                       static_cast<std::size_t>(data_length)) );
+        else if (get_type_v4() == Icmpv4Type_DestinationUnreachable
+              || get_type_v6() == Icmpv6Type_DestinationUnreachable)
+            icmp_data_ptr.reset( new IcmpDestinationUnreachableData(
+                                       static_cast<std::size_t>(data_length)) );
+        else
+            return ReadReturnCode_UNKNOWN_ICMP_TYPE;
+        icmp_data_ptr->read( is );
+    }
+
+    if ( is.eof() )
+        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
+    else if ( !is.good() )
+        return IcmpPacket::ReadReturnCode_BAD_STREAM;
+    else
+        return IcmpPacket::ReadReturnCode_OK;
 }
 
 
@@ -51,6 +126,9 @@ std::string IcmpPacket::return_code_to_string( const IcmpPacket::ReadReturnCode
     case IcmpPacket::ReadReturnCode_BAD_STREAM: return "bad stream!"; break;
     case IcmpPacket::ReadReturnCode_INVALID_SIZE: return "invalid data size!"; break;
     case IcmpPacket::ReadReturnCode_UNKNOWN_PROTOCOL: return "unknown protocol, expect ICMPv4/6!"; break;
+    case IcmpPacket::ReadReturnCode_UNKNOWN_ICMP_TYPE:
+      return "unknown icmp type, expect echo request/reply or destination unreachable!";
+      break;
     }
 
     // if nothing matched
@@ -58,6 +136,26 @@ std::string IcmpPacket::return_code_to_string( const IcmpPacket::ReadReturnCode
 }
 
 /**
+ * @brief Write the ICMP packet to the @c ostream.
+ *
+ * the IP header is not written to stream!
+ * (is usually all 0s anyway)
+ *
+ * @param os The output stream.
+ *
+ * @return @c true if the write was successful, or @c false if an error occurred.
+ */
+bool IcmpPacket::write( std::ostream &os ) const
+{
+    os.clear();
+
+    icmp_header.write(os);
+    icmp_data_ptr->write(os);
+
+    return !os.fail();
+}
+
+/**
  * @brief create packet from data in @a is;  calls IcmpPacket::read
  *
  * @param is input stream with hopefully sufficient data
@@ -85,3 +183,5 @@ std::ostream& operator<<(
     packet.write( os );
     return os;
 }
+
+// (created using vim -- the world's best text editor)
index 139957e..d726ca5 100644 (file)
@@ -1,47 +1,54 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
+/*
+ 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
+ */
+
 #ifndef ICMP_PACKET_H
 #define ICMP_PACKET_H
 
 #include <stdint.h>
-
 #include <iostream>
 
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/icmp.hpp>
+#include <boost/date_time/posix_time/ptime.hpp>
 
-//-----------------------------------------------------------------------------
-// IcmpPacket
-//-----------------------------------------------------------------------------
+#include "ip/ipheader.h"
+#include "ip/ipv4header.h"
+#include "ip/ipv6header.h"
+#include "icmp/icmpheader.h"
+#include "icmp/icmpdata.h"
+#include "icmp/icmptype.h"
 
-/**
- * @brief Abstract class for ICMP Packets.
- */
-class IcmpPacket : boost::noncopyable
+using boost::asio::ip::icmp;
+using boost::asio::ip::address;
+
+class IcmpPacket
 {
+protected:
+    IpHeaderPtr ip_head_ptr;
+    IcmpHeader icmp_header;
+    IcmpDataPtr icmp_data_ptr;
+
 public:
-    virtual bool match_echo_reply(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const = 0;
-    virtual bool match_destination_unreachable(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const = 0;
-
-    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;
 
     enum ReadReturnCode {
         ReadReturnCode_OK = 0,
@@ -50,33 +57,102 @@ public:
         ReadReturnCode_NOT_ENOUGH_DATA,
         ReadReturnCode_BAD_STREAM,
         ReadReturnCode_INVALID_SIZE,
-        ReadReturnCode_UNKNOWN_PROTOCOL
+        ReadReturnCode_UNKNOWN_PROTOCOL,
+        ReadReturnCode_UNKNOWN_ICMP_TYPE
     };
 
     static std::string return_code_to_string( const ReadReturnCode &code );
 
-    virtual ReadReturnCode read( std::istream &is ) = 0;
-    virtual bool write( std::ostream &os ) const = 0;
+    IcmpPacket()
+        : ip_head_ptr()
+        , icmp_header()
+        , icmp_data_ptr()
+    {}
 
-    friend std::istream& operator>>(
-            std::istream &is,
-            IcmpPacket &packet
-    );
-    friend std::ostream& operator<<(
-            std::ostream &os,
-            const IcmpPacket &packet
-    );
+    // 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!" );
 
-protected:
-    IcmpPacket();
-    virtual ~IcmpPacket();
+        // 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);
+    }
 
-//-----------------------------------------------------------------------------
-// IcmpPacketItem
-//-----------------------------------------------------------------------------
+    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);
+    }
+
+    /**
+     * @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 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);
+    }
+
+    ReadReturnCode read(std::istream &is);
+
+    bool write(std::ostream &os) const;
+};
 
 typedef boost::shared_ptr<IcmpPacket> IcmpPacketItem;
 
-#endif // ICMP_PACKET_H
+#endif
+
+// (created using vim -- the world's best text editor)
+
index 448e5c0..ddfd9fe 100644 (file)
 #include <logfunc.hpp>
 
 #include "boost_assert_handler.h"
-#include "icmp/icmpchecksum.h"
 #include "icmp/icmpdata.h"
+#include "icmp/icmpheader.h"
 #include "icmp/icmptype.h"
-#include "icmp/icmpv4header.h"
-#include "icmp/icmpv4packet.h"
-#include "icmp/icmpv6header.h"
-#include "icmp/icmpv6packet.h"
+#include "icmp/icmpechodata.h"
 
 using namespace std;
 using boost::asio::ip::icmp;
@@ -145,14 +142,8 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
 {
     IcmpPacketItem icmp_packet;
 
-    if ( icmp::v4() == protocol )
-    {
-        icmp_packet.reset( new Icmpv4Packet() );
-    }
-    else if ( icmp::v6() == protocol )
-    {
-        icmp_packet.reset( new Icmpv6Packet() );
-    }
+    if ( icmp::v4() == protocol || icmp::v6() == protocol )
+        icmp_packet.reset( new IcmpPacket() );
     else
     {
         GlobalLogger.warning() << "ICMP packet creation failed: "
@@ -224,80 +215,23 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet_echo_request(
 {
     BOOST_ASSERT( (icmp::v4() == protocol) || (icmp::v6() == protocol) );
 
-    IcmpPacketItem icmp_packet;
-
+    uint8_t type;
     if ( icmp::v4() == protocol )
-    {
-        icmp_packet = create_icmpv4_packet_echo_request( identifier, sequence_number );
-    }
+        type = static_cast<uint8_t>(Icmpv4Type_EchoRequest);
     else if ( icmp::v6() == protocol )
-    {
-        icmp_packet = create_icmpv6_packet_echo_request( identifier, sequence_number );
-    }
-    else
-    {
-        BOOST_ASSERT( !"Invalid ICMP Packet Type." );                                                                                               //lint !e506
-    }
-
-    return icmp_packet;
-}
-
-/**
- * @brief Creates an ICMPv4 Echo Request packet.
- *
- * @param identifier The packet's identifier number.
- * @param sequence_number The packet's sequence number.
- *
- * @return An ICMPv4 Echo Request packet object.
- */
-IcmpPacketItem IcmpPacketFactory::create_icmpv4_packet_echo_request(
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    const IcmpData icmp_data( "ping-message" );
+        type = static_cast<uint8_t>(Icmpv6Type_EchoRequest);
+    // other case caught be BOOST_ASSERT above
 
-    Icmpv4Type type = Icmpv4Type_EchoRequest;
     uint8_t code = 0;
-    IcmpChecksum calculator( icmp_data.begin(), icmp_data.end() );
-    uint16_t checksum = calculator.compute(
-            type, code, identifier, sequence_number
-    );
-    Icmpv4Header icmp_header(
-            type, code, checksum, identifier, sequence_number
-    );
-    IcmpPacketItem icmp_packet( new Icmpv4Packet( icmp_header, icmp_data ) );
-
-    return icmp_packet;
-}
+    IcmpHeader icmp_header( type, code );
 
-/**
- * @brief Creates an ICMPv6 Echo Request packet.
- *
- * @param identifier The packet's identifier number.
- * @param sequence_number The packet's sequence number.
- *
- * @return An ICMPv6 Echo Request packet object.
- */
-IcmpPacketItem IcmpPacketFactory::create_icmpv6_packet_echo_request(
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    const IcmpData icmp_data( "ping-message" );
+    IcmpDataPtr icmp_data( new IcmpEchoData( identifier, sequence_number,
+                                                "ping-message" ) );
 
-    Icmpv6Type type = Icmpv6Type_EchoRequest;
-    uint8_t code = 0;
-    IcmpChecksum calculator( icmp_data.begin(), icmp_data.end() );
-    uint16_t checksum = calculator.compute(
-            type, code, identifier, sequence_number
-    );
-    Icmpv6Header icmp_header(
-            type, code, checksum, identifier, sequence_number
-    );
-    IcmpPacketItem icmp_packet( new Icmpv6Packet( icmp_header, icmp_data ) );
+    IcmpPacketItem icmp_packet( new IcmpPacket( protocol,
+                                                icmp_header,
+                                                icmp_data ) );
 
     return icmp_packet;
 }
 
-
index 9d2f864..496738e 100644 (file)
@@ -320,7 +320,7 @@ bool IcmpPinger::handle_receive_icmp_packet(const IcmpPacketItem icmp_packet,
         ReplyReceived = true;
         does_match = true;
 
-        icmp_packet->print_echo_reply( bytes_transferred, TimeSent );
+        icmp_packet->print( bytes_transferred, TimeSent );
 
         set_ping_status( PingStatus_SuccessReply );
 
@@ -337,7 +337,7 @@ bool IcmpPinger::handle_receive_icmp_packet(const IcmpPacketItem icmp_packet,
         ReplyReceived = true;
         does_match = true;
 
-        icmp_packet->print_destination_unreachable();
+        icmp_packet->print( bytes_transferred, TimeSent );
 
         set_ping_status( PingStatus_FailureDestinationUnreachable );
 
diff --git a/src/icmp/icmpv4header.cpp b/src/icmp/icmpv4header.cpp
deleted file mode 100644 (file)
index 1f0e680..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpv4header.h"
-
-#include "boost_assert_handler.h"
-#include "icmp/icmpdestinationunreachablemessage.h"
-#include "icmp/icmpechoreplymessage.h"
-#include "icmp/icmpechorequestmessage.h"
-#include "icmp/icmpgenericmessage.h"
-
-#include <logfunc.hpp>
-using I2n::Logger::GlobalLogger;
-
-using namespace std;
-using boost::shared_ptr;
-
-//-----------------------------------------------------------------------------
-// Icmpv4Header
-//-----------------------------------------------------------------------------
-
-static const size_t HeaderSizeInBytes = 8;
-
-Icmpv4Header::Icmpv4Header() :
-    MessageFormat()
-{
-}
-
-Icmpv4Header::Icmpv4Header(
-        const Icmpv4Type type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-) :
-    MessageFormat()
-{
-    set_icmp_message_format( type );
-
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
-}
-
-Icmpv4Type Icmpv4Header::get_type() const
-{
-    return get_icmp_message_format()->get_type_v4();
-}
-
-void Icmpv4Header::set_type( const Icmpv4Type type )
-{
-    get_icmp_message_format()->set_type_v4( type );
-} //lint !e1762
-
-uint8_t Icmpv4Header::get_code() const
-{
-    return get_icmp_message_format()->get_code();
-}
-
-void Icmpv4Header::set_code( const uint8_t code )
-{
-    get_icmp_message_format()->set_code( code );
-} //lint !e1762
-
-uint16_t Icmpv4Header::get_checksum() const
-{
-    return get_icmp_message_format()->get_checksum();
-}
-
-void Icmpv4Header::set_checksum( const uint16_t checksum )
-{
-    get_icmp_message_format()->set_checksum( checksum );
-} //lint !e1762
-
-uint16_t Icmpv4Header::get_identifier() const
-{
-    return get_icmp_message_format()->get_identifier();
-}
-
-void Icmpv4Header::set_identifier( const uint16_t identifier )
-{
-    get_icmp_message_format()->set_identifier( identifier );
-} //lint !e1762
-
-uint16_t Icmpv4Header::get_sequence_number() const
-{
-    return get_icmp_message_format()->get_sequence_number();
-}
-
-void Icmpv4Header::set_sequence_number( const uint16_t sequence_number )
-{
-    get_icmp_message_format()->set_sequence_number( sequence_number );
-} //lint !e1762
-
-shared_ptr<IcmpMessage> Icmpv4Header::get_icmp_message_format() const
-{
-    BOOST_ASSERT( MessageFormat.get() != NULL );
-
-    return MessageFormat;
-}
-
-void Icmpv4Header::set_icmp_message_format( const Icmpv4Type type )
-{
-    BOOST_ASSERT( MessageFormat.get() == NULL );
-
-    if ( MessageFormat.get() == NULL )
-    {
-        switch ( type )
-        {
-            case Icmpv4Type_EchoReply:
-                MessageFormat.reset( new IcmpEchoReplyMessage );
-                break;
-            case Icmpv4Type_EchoRequest:
-                MessageFormat.reset( new IcmpEchoRequestMessage );
-                break;
-            case Icmpv4Type_DestinationUnreachable:
-                MessageFormat.reset(
-                        new IcmpDestinationUnreachableMessage
-                );
-                break;
-            case Icmpv4Type_SourceQuench:
-            case Icmpv4Type_Redirect:
-            case Icmpv4Type_TimeExceeded:
-            case Icmpv4Type_ParameterProblem:
-            case Icmpv4Type_TimestampRequest:
-            case Icmpv4Type_TimestampReply:
-            case Icmpv4Type_InfoRequest:
-            case Icmpv4Type_InfoReply:
-            case Icmpv4Type_AddressRequest:
-            case Icmpv4Type_AddressReply:
-            case Icmpv4Type_Generic:
-                MessageFormat.reset( new IcmpGenericMessage );
-                break;
-            case Icmpv4Type_InvalidLast:
-            default:
-                GlobalLogger.error() << "Invalid ICMPv4 message type " << static_cast<int>(type) << "!";
-                BOOST_ASSERT( !"Try to set an invalid ICMPv4 message type" );
-                break;
-        }
-
-        MessageFormat->init( type );
-    }
-
-    BOOST_ASSERT( MessageFormat.get() != NULL );
-    BOOST_ASSERT( MessageFormat->get_type_v4() != Icmpv4Type_InvalidLast );
-}
-
-void Icmpv4Header::set_icmp_message_format( std::istream &is )
-{
-    // read the first byte, which contains the type of the ICMP message
-    char first_byte;
-    (void) is.read( &first_byte, 1 );
-
-    // must keep the stream intact, so place the read byte back
-    (void) is.putback( first_byte );
-
-    // now select the message format for the given type
-    Icmpv4Type header_type = static_cast<Icmpv4Type>( first_byte );
-    set_icmp_message_format( header_type );
-}
-
-size_t Icmpv4Header::get_header_length() const
-{
-    return HeaderSizeInBytes;
-}
-
-std::istream& operator>>(
-        std::istream &is,
-        Icmpv4Header &header
-)
-{
-    // select the message format which will parse the fields
-    header.set_icmp_message_format( is );
-
-    // delegate the parsing of the fields to a specialized decoder
-    return header.get_icmp_message_format()->read( is );
-}
-
-std::ostream& operator<<(
-        std::ostream &os,
-        const Icmpv4Header &header
-)
-{
-    // delegate the writing of the fields to a specialized encoder
-    return header.get_icmp_message_format()->write( os );
-}
diff --git a/src/icmp/icmpv4header.h b/src/icmp/icmpv4header.h
deleted file mode 100644 (file)
index 86173c1..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMPV4_HEADER_H
-#define ICMPV4_HEADER_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include <boost/shared_ptr.hpp>
-
-#include "icmp/icmpmessage.h"
-#include "icmp/icmptype.h"
-
-//-----------------------------------------------------------------------------
-// Icmpv4Header
-//-----------------------------------------------------------------------------
-
-/**
- * @brief This class represents the ICMP version 4 Header.
- *
- * The ICMP Generic Header Format is:
- *
- * @code
- * 0               8               16                             31
- * +---------------+---------------+------------------------------+     ---
- * |               |               |                              |      ^
- * |     type      |     code      |          checksum            |   4 bytes
- * |               |               |                              |      v
- * +---------------+---------------+------------------------------+     ---
- * |                                                              |
- * |                     specific to each message                 |
- * |                                                              |
- * +-------------------------------+------------------------------+
- * @endcode
- */
-class Icmpv4Header
-{
-public:
-    Icmpv4Header();
-    Icmpv4Header(
-            const Icmpv4Type type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
-
-    Icmpv4Type get_type() const;
-    void set_type( const Icmpv4Type type );
-
-    uint8_t get_code() const;
-    void set_code( const uint8_t code );
-
-    uint16_t get_checksum() const;
-    void set_checksum( const uint16_t checksum );
-
-    uint16_t get_identifier() const;
-    void set_identifier( const uint16_t identifier );
-
-    uint16_t get_sequence_number() const;
-    void set_sequence_number( const uint16_t sequence_number );
-
-    boost::shared_ptr<IcmpMessage> get_icmp_message_format() const;
-    void set_icmp_message_format( const Icmpv4Type type );
-    void set_icmp_message_format( std::istream &is );
-
-    size_t get_header_length() const;
-
-    friend std::istream& operator>>(
-            std::istream &is,
-            Icmpv4Header &header
-    );
-    friend std::ostream& operator<<(
-            std::ostream &os,
-            const Icmpv4Header &header
-    );
-
-private:
-    /// Changeable pointer to different ICMP messages types.
-    boost::shared_ptr<IcmpMessage> MessageFormat;
-
-};
-
-#endif // ICMPV4_HEADER_H
diff --git a/src/icmp/icmpv4packet.cpp b/src/icmp/icmpv4packet.cpp
deleted file mode 100644 (file)
index 82ed70d..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpv4packet.h"
-
-#include <iostream>
-
-#include <logfunc.hpp>
-#include <boost/scoped_array.hpp>
-
-#include "boost_assert_handler.h"
-
-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 boost::scoped_array;
-using I2n::Logger::GlobalLogger;
-
-//-----------------------------------------------------------------------------
-// Icmpv4Packet
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Default constructor.
- */
-Icmpv4Packet::Icmpv4Packet() :
-    IpHeader(),
-    IcmpPayloadHeader(),
-    IcmpPayloadData()
-{
-}
-
-/**
- * @brief Parameterized constructor.
- *
- * @param icmp_header The ICMP header.
- * @param icmp_data The ICMP payload data.
- */
-Icmpv4Packet::Icmpv4Packet(
-        const Icmpv4Header &icmp_header,
-        const IcmpData &icmp_data
-) :
-    IpHeader(),
-    IcmpPayloadHeader( icmp_header ),
-    IcmpPayloadData( icmp_data )
-{
-}
-
-/**
- * @brief Destructor.
- */
-Icmpv4Packet::~Icmpv4Packet()
-{
-}
-
-/**
- * @brief Obtain the IP header.
- *
- * @return The IP header object.
- */
-Ipv4Header Icmpv4Packet::get_ip_header() const
-{
-    return IpHeader;
-}
-
-/**
- * @brief Obtain the ICMP header.
- *
- * @return The ICMP header object.
- */
-Icmpv4Header Icmpv4Packet::get_icmp_header() const
-{
-    return IcmpPayloadHeader;
-}
-
-/**
- * @brief Obtain the ICMP payload data.
- *
- * @return The ICMP data.
- */
-IcmpData Icmpv4Packet::get_icmp_data() const
-{
-    return IcmpPayloadData;
-}
-
-/**
- * @brief Convenience method to check if this packet, matching the arguments,
- * is an echo reply.
- *
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this packet is an echo reply, or @c false otherwise.
- */
-bool Icmpv4Packet::match_echo_reply(
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v4() );
-
-    return match( Icmpv4Type_EchoReply, identifier, sequence_number, source_address );
-}
-
-/**
- * @brief Convenience method to check if this packet, matching the arguments,
- * is a destination unreachable.
- *
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this packet is a destination unreachable, or @c false
- * otherwise.
- */
-bool Icmpv4Packet::match_destination_unreachable(
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v4() );
-
-    return match( Icmpv4Type_DestinationUnreachable, identifier, sequence_number, source_address );
-}
-
-/**
- * @brief Check if this object matches with all the parameters.
- *
- * @param type The type of ICMP message.
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this matches all the parameters, or @c false if at least
- * one does not match.
- */
-bool Icmpv4Packet::match(
-        const Icmpv4Type type,
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v4() );
-
-    bool type_match = IcmpPayloadHeader.get_type() == type ? true : false;
-    bool identifier_match = IcmpPayloadHeader.get_identifier() == identifier ? true: false;
-    bool seq_num_match = IcmpPayloadHeader.get_sequence_number() == sequence_number ? true : false;
-    bool address_match = IpHeader.get_source_address() == source_address ? true : false;
-
-    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();
-    uint32_t 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;
-}
-
-/**
- * @brief Read (part of) the ICMP packet from the input stream @a is
- *
- * @param is The input stream.
- *
- * @return result of the read, currently one of {ok, fail, not enough data}
- */
-IcmpPacket::ReadReturnCode Icmpv4Packet::read( istream &is )
-{
-    if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-
-    // try to read ip header
-    is >> IpHeader;
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-
-    // try to read the icmp header
-    is >> IcmpPayloadHeader;
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-
-    // calculate the size of the ICMP data
-    streamsize data_length = static_cast<streamsize>( IpHeader.get_total_length() )
-                           - static_cast<streamsize>( IpHeader.get_header_length() )
-                           - static_cast<streamsize>( IcmpPayloadHeader.get_header_length() );
-
-    // try to read that amount of data
-    if ( data_length < 0 )
-    {
-        GlobalLogger.error() << "Invalid size for optional ICMP data: "
-                             << data_length << endl;
-        is.setstate( ios::failbit );
-        return IcmpPacket::ReadReturnCode_INVALID_SIZE;
-    }
-    else if ( data_length > 0 )
-    {
-        size_t options_size = static_cast<size_t>( data_length );
-        scoped_array<uint8_t> scoped_data( new uint8_t[options_size+1] ); // need a 0 after data
-        memset(scoped_data.get(), 0, (options_size+1)*sizeof(uint8_t));
-        char *char_data = reinterpret_cast<char *>( scoped_data.get() );
-
-        (void) is.read( char_data, data_length );    // leave 0 at the end
-        IcmpPayloadData = char_data;  // implicit cast
-    }
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-    else
-        return IcmpPacket::ReadReturnCode_OK;
-}
-
-/**
- * @brief Write the ICMP packet to the @c ostream.
- *
- * @param os The output stream.
- *
- * @return @c true if the write was successful, or @c false if an error occurred.
- */
-bool Icmpv4Packet::write( std::ostream &os ) const
-{
-    os.clear();
-
-    os << IcmpPayloadHeader << IcmpPayloadData;
-
-    return !os.fail();
-}
-
diff --git a/src/icmp/icmpv4packet.h b/src/icmp/icmpv4packet.h
deleted file mode 100644 (file)
index 1c0d075..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMPV4_PACKET_H
-#define ICMPV4_PACKET_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include <boost/asio.hpp>
-
-#include "icmp/icmppacket.h"
-#include "icmp/icmpv4header.h"
-#include "icmp/icmpdata.h"
-#include "icmp/icmptype.h"
-#include "ip/ipv4header.h"
-
-//-----------------------------------------------------------------------------
-// Icmpv4Packet
-//-----------------------------------------------------------------------------
-
-/**
- * @brief This class represents the ICMP version 4 Packet.
- *
- * The ICMP Packet format is:
- *
- * @code
- * 0               8               16                             31
- * +-------+-------+---------------+------------------------------+      ---
- * |       |       |               |                              |       ^
- * |version|header |    type of    |    total length in bytes     |       |
- * |  (4)  | length|    service    |                              |       |
- * +-------+-------+---------------+-+-+-+------------------------+       |
- * |                               | | | |                        |       |
- * |        identification         |0|D|M|    fragment offset     |       |
- * |                               | |F|F|                        |       |
- * +---------------+---------------+-+-+-+------------------------+       |
- * |               |               |                              |       |
- * | time to live  |   protocol    |       header checksum        |  IPv4 Header
- * |               |               |                              |   20 bytes
- * +---------------+---------------+------------------------------+       |
- * |                                                              |       |
- * |                      source IPv4 address                     |       |
- * |                                                              |       |
- * +--------------------------------------------------------------+       |
- * |                                                              |       |
- * |                   destination IPv4 address                   |       |
- * |                                                              |       v
- * +---------------+---------------+------------------------------+      ---
- * |               |               |                              |       ^
- * |     type      |     code      |          checksum            |       |
- * |               |               |                              |       |
- * +---------------+---------------+------------------------------+       |
- * |                               |                              | ICMP Payload
- * |          identifier           |       sequence number        | (header +
- * |                               |                              |       data)
- * +-------------------------------+------------------------------+   8+ bytes
- * |                                                              |       |
- * |                      data (optional)                         |       |
- * |                                                              |       v
- * +-------------------------------+------------------------------+      ---
- * @endcode
- */
-class Icmpv4Packet : public IcmpPacket
-{
-public:
-    Icmpv4Packet();
-    Icmpv4Packet(
-            const Icmpv4Header &icmp_header,
-            const IcmpData &icmp_data
-    );
-    virtual ~Icmpv4Packet();
-
-    Ipv4Header get_ip_header() const;
-    Icmpv4Header get_icmp_header() const;
-    IcmpData get_icmp_data() const;
-
-    virtual bool match_echo_reply(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-    virtual bool match_destination_unreachable(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-
-    virtual void print_echo_reply(
-            const std::size_t &bytes_transferred,
-            const boost::posix_time::ptime &time_packet_sent
-    ) const;
-    virtual void print_destination_unreachable() const;
-
-    virtual ReadReturnCode read( std::istream &is );
-    bool write( std::ostream &os ) const;
-
-
-private:
-    bool match(
-            const Icmpv4Type type,
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-
-private:
-    /// The IP header.
-    Ipv4Header IpHeader;
-    /// The ICMP packet header.
-    Icmpv4Header IcmpPayloadHeader;
-    /// The ICMP packet payload (data).
-    IcmpData IcmpPayloadData;
-};
-
-#endif // ICMPV4_PACKET_H
diff --git a/src/icmp/icmpv6header.cpp b/src/icmp/icmpv6header.cpp
deleted file mode 100644 (file)
index fd5425d..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpv6header.h"
-
-#include "boost_assert_handler.h"
-#include "icmp/icmpdestinationunreachablemessage.h"
-#include "icmp/icmpechoreplymessage.h"
-#include "icmp/icmpechorequestmessage.h"
-#include "icmp/icmpgenericmessage.h"
-
-using namespace std;
-using boost::shared_ptr;
-
-//-----------------------------------------------------------------------------
-// Icmpv6Header
-//-----------------------------------------------------------------------------
-
-static const size_t HeaderSizeInBytes = 4;
-
-Icmpv6Header::Icmpv6Header() :
-    MessageFormat()
-{
-}
-
-Icmpv6Header::Icmpv6Header(
-        const Icmpv6Type type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-) :
-    MessageFormat()
-{
-    set_icmp_message_format( type );
-
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
-}
-
-Icmpv6Type Icmpv6Header::get_type() const
-{
-    return get_icmp_message_format()->get_type_v6();
-}
-
-void Icmpv6Header::set_type( const Icmpv6Type type )
-{
-    get_icmp_message_format()->set_type_v6( type );
-} //lint !e1762
-
-uint8_t Icmpv6Header::get_code() const
-{
-    return get_icmp_message_format()->get_code();
-}
-
-void Icmpv6Header::set_code( const uint8_t code )
-{
-    get_icmp_message_format()->set_code( code );
-} //lint !e1762
-
-uint16_t Icmpv6Header::get_checksum() const
-{
-    return get_icmp_message_format()->get_checksum();
-}
-
-void Icmpv6Header::set_checksum( const uint16_t checksum )
-{
-    get_icmp_message_format()->set_checksum( checksum );
-} //lint !e1762
-
-uint16_t Icmpv6Header::get_identifier() const
-{
-    return get_icmp_message_format()->get_identifier();
-}
-
-void Icmpv6Header::set_identifier( const uint16_t identifier )
-{
-    get_icmp_message_format()->set_identifier( identifier );
-} //lint !e1762
-
-uint16_t Icmpv6Header::get_sequence_number() const
-{
-    return get_icmp_message_format()->get_sequence_number();
-}
-
-void Icmpv6Header::set_sequence_number( const uint16_t sequence_number )
-{
-    get_icmp_message_format()->set_sequence_number( sequence_number );
-} //lint !e1762
-
-shared_ptr<IcmpMessage> Icmpv6Header::get_icmp_message_format() const
-{
-    BOOST_ASSERT( MessageFormat.get() != NULL );
-
-    return MessageFormat;
-}
-
-void Icmpv6Header::set_icmp_message_format( const Icmpv6Type type )
-{
-    BOOST_ASSERT( MessageFormat.get() == NULL );
-
-    if ( MessageFormat.get() == NULL )
-    {
-        switch ( type )
-        {
-            case Icmpv6Type_EchoReply:
-                MessageFormat.reset( new IcmpEchoReplyMessage );
-                break;
-            case Icmpv6Type_EchoRequest:
-                MessageFormat.reset( new IcmpEchoRequestMessage );
-                break;
-            case Icmpv6Type_DestinationUnreachable:
-                MessageFormat.reset(
-                        new IcmpDestinationUnreachableMessage
-                );
-                break;
-            case Icmpv6Type_PacketTooBig:
-            case Icmpv6Type_TimeExceeded:
-            case Icmpv6Type_ParameterProblem:
-            case Icmpv6Type_RouterSolicitation:
-            case Icmpv6Type_RouterAdvertisement:
-            case Icmpv6Type_NeighborSolicitation:
-            case Icmpv6Type_NeighborAdvertisement:
-            case Icmpv6Type_RedirectMessage:
-            case Icmpv6Type_RouterRenumbering:
-            case Icmpv6Type_ICMPNodeInformationQuery:
-            case Icmpv6Type_ICMPNodeInformationResponse:
-            case Icmpv6Type_InverseNeighborDiscoverySolicitationMessage:
-            case Icmpv6Type_InverseNeighborDiscoveryAdvertisementMessage:
-            case Icmpv6Type_MulticastListenerDiscovery:
-            case Icmpv6Type_HomeAgentAddressDiscoveryRequestMessage:
-            case Icmpv6Type_HomeAgentAddressDiscoveryReplyMessage:
-            case Icmpv6Type_MobilePrefixSolicitation:
-            case Icmpv6Type_MobilePrefixAdvertisement:
-            case Icmpv6Type_CertificationPathSolicitation:
-            case Icmpv6Type_CertificationPathAdvertisement:
-            case Icmpv6Type_MulticastRouterAdvertisement:
-            case Icmpv6Type_MulticastRouterSolicitation:
-            case Icmpv6Type_MulticastRouterTermination:
-            case Icmpv6Type_Generic:
-                MessageFormat.reset( new IcmpGenericMessage );
-                break;
-            case Icmpv6Type_First:
-            case Icmpv6Type_InvalidLast:
-            default:
-                BOOST_ASSERT( !"Try to set an invalid ICMPv6 message type" );
-                break;
-        }
-
-        MessageFormat->init( type );
-    }
-
-    BOOST_ASSERT( MessageFormat.get() != NULL );
-    BOOST_ASSERT( MessageFormat->get_type_v6() != Icmpv6Type_InvalidLast );
-}
-
-void Icmpv6Header::set_icmp_message_format( std::istream &is )
-{
-    // read the first byte, which contains the type of the ICMP message
-    uint8_t first_byte = 0;
-    (void) is.read( reinterpret_cast<char *>(&first_byte), 1 );
-
-    // must keep the stream intact, so place the read byte back
-    (void) is.putback( static_cast<std::istream::char_type>(first_byte) );
-
-    // now select the message format for the given type
-    Icmpv6Type header_type = static_cast<Icmpv6Type>( first_byte );
-    set_icmp_message_format( header_type );
-}
-
-size_t Icmpv6Header::get_header_length() const
-{
-    return HeaderSizeInBytes;
-}
-
-std::istream& operator>>(
-        std::istream &is,
-        Icmpv6Header &header
-)
-{
-    // select the message format which will parse the fields
-    header.set_icmp_message_format( is );
-
-    // delegate the parsing of the fields to a specialized decoder
-    return header.get_icmp_message_format()->read( is );
-}
-
-std::ostream& operator<<(
-        std::ostream &os,
-        const Icmpv6Header &header
-)
-{
-    // delegate the writing of the fields to a specialized encoder
-    return header.get_icmp_message_format()->write( os );
-}
diff --git a/src/icmp/icmpv6header.h b/src/icmp/icmpv6header.h
deleted file mode 100644 (file)
index 3aec4b0..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMPV6_HEADER_H
-#define ICMPV6_HEADER_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include <boost/shared_ptr.hpp>
-
-#include "icmp/icmpmessage.h"
-#include "icmp/icmptype.h"
-
-//-----------------------------------------------------------------------------
-// Icmpv6Header
-//-----------------------------------------------------------------------------
-
-/**
- * @brief This class represents the ICMP version 6 Header.
- *
- * The ICMP Generic Header Format is:
- *
- * @code
- * 0               8               16                             31
- * +---------------+---------------+------------------------------+     ---
- * |               |               |                              |      ^
- * |     type      |     code      |          checksum            |   4 bytes
- * |               |               |                              |      v
- * +---------------+---------------+------------------------------+     ---
- * |                                                              |
- * |                     specific to each message                 |
- * |                                                              |
- * +-------------------------------+------------------------------+
- * @endcode
- */
-class Icmpv6Header
-{
-public:
-    Icmpv6Header();
-    Icmpv6Header(
-            const Icmpv6Type type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
-
-    Icmpv6Type get_type() const;
-    void set_type( const Icmpv6Type type );
-
-    uint8_t get_code() const;
-    void set_code( const uint8_t code );
-
-    uint16_t get_checksum() const;
-    void set_checksum( const uint16_t checksum );
-
-    uint16_t get_identifier() const;
-    void set_identifier( const uint16_t identifier );
-
-    uint16_t get_sequence_number() const;
-    void set_sequence_number( const uint16_t sequence_number );
-
-    boost::shared_ptr<IcmpMessage> get_icmp_message_format() const;
-    void set_icmp_message_format( const Icmpv6Type type );
-    void set_icmp_message_format( std::istream &is );
-
-    size_t get_header_length() const;
-
-    friend std::istream& operator>>(
-            std::istream &is,
-            Icmpv6Header &header
-    );
-    friend std::ostream& operator<<(
-            std::ostream &os,
-            const Icmpv6Header &header
-    );
-
-private:
-    /// Changeable pointer to different ICMP messages types.
-    boost::shared_ptr<IcmpMessage> MessageFormat;
-
-};
-
-#endif // ICMPV6_HEADER_H
diff --git a/src/icmp/icmpv6packet.cpp b/src/icmp/icmpv6packet.cpp
deleted file mode 100644 (file)
index 6e8dfb8..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#include "icmp/icmpv6packet.h"
-
-#include <iostream>
-
-#include <logfunc.hpp>
-#include <boost/scoped_array.hpp>
-
-#include "boost_assert_handler.h"
-
-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 boost::scoped_array;
-using I2n::Logger::GlobalLogger;
-
-//-----------------------------------------------------------------------------
-// Icmpv6Packet
-//-----------------------------------------------------------------------------
-
-/**
- * @brief Default constructor.
- */
-Icmpv6Packet::Icmpv6Packet() :
-    IpHeader(),
-    IcmpPayloadHeader(),
-    IcmpPayloadData()
-{
-}
-
-/**
- * @brief Parameterized constructor.
- *
- * @param icmp_header The ICMP header.
- * @param icmp_data The ICMP payload data.
- */
-Icmpv6Packet::Icmpv6Packet(
-        const Icmpv6Header &icmp_header,
-        const IcmpData &icmp_data
-) :
-    IpHeader(),
-    IcmpPayloadHeader( icmp_header ),
-    IcmpPayloadData( icmp_data )
-{
-}
-
-/**
- * @brief Destructor.
- */
-Icmpv6Packet::~Icmpv6Packet()
-{
-}
-
-/**
- * @brief Obtain the IP header.
- *
- * @return The IP header object.
- */
-Ipv6Header Icmpv6Packet::get_ip_header() const
-{
-    return IpHeader;
-}
-
-/**
- * @brief Obtain the ICMP header.
- *
- * @return The ICMP header object.
- */
-Icmpv6Header Icmpv6Packet::get_icmp_header() const
-{
-    return IcmpPayloadHeader;
-}
-
-/**
- * @brief Obtain the ICMP payload data.
- *
- * @return The ICMP data.
- */
-IcmpData Icmpv6Packet::get_icmp_data() const
-{
-    return IcmpPayloadData;
-}
-
-/**
- * @brief Convenience method to check if this packet, matching the arguments,
- * is a echo reply.
- *
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this packet is a echo reply, or @c false otherwise.
- */
-bool Icmpv6Packet::match_echo_reply(
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v6() );
-
-    return match( Icmpv6Type_EchoReply, identifier, sequence_number, source_address );
-}
-
-/**
- * @brief Convenience method to check if this packet, matching the arguments,
- * is a destination unreachable.
- *
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this packet is a destination unreachable, or @c false
- * otherwise.
- */
-bool Icmpv6Packet::match_destination_unreachable(
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v6() );
-
-    return match( Icmpv6Type_DestinationUnreachable, identifier, sequence_number, source_address );
-}
-
-/**
- * @brief Check if this object matches with all the parameters.
- *
- * @param type The type of ICMP message.
- * @param identifier The identifier.
- * @param sequence_number The sequence number.
- * @param source_address The source address.
- *
- * @return @c true if this matches all the parameters, or @c false if at least
- * one does not match.
- */
-bool Icmpv6Packet::match(
-        const Icmpv6Type type,
-        const uint16_t identifier,
-        const uint16_t sequence_number,
-        const address &source_address
-) const
-{
-    BOOST_ASSERT( source_address.is_v6() );
-
-    bool type_match = IcmpPayloadHeader.get_type() == type ? true : false;
-    bool identifier_match = IcmpPayloadHeader.get_identifier() == identifier ? true: false;
-    bool seq_num_match = IcmpPayloadHeader.get_sequence_number() == sequence_number ? true : false;
-#ifdef IPV6_DATA_PRESENT_IN_ISTREAM
-    // TODO operator>> does not read IpHeader, thus this object is not initialized
-    // must check why IPv6 data does not come in the istream like IPv4 data
-    bool address_match = IpHeader.get_source_address() == source_address ? true : false;
-
-    return ( type_match && identifier_match && seq_num_match && address_match );
-#else
-
-    return ( type_match && identifier_match && seq_num_match );
-#endif
-}
-
-/**
- * @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();
-#ifdef IPV6_DATA_PRESENT_IN_ISTREAM
-    //TODO WHY IPv6 does not come like IPv4????
-    string remote_address = ipv6_header.get_source_address().to_string();
-#else
-    string remote_address = "?";
-#endif
-
-    uint16_t sequence_number = icmpv6_header.get_sequence_number();
-    uint32_t 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;
-}
-
-/**
- * @brief Read (part of) the ICMP packet from the input stream @a is
- *
- * @param is The input stream.
- *
- * @return result of the read, currently one of {ok, fail, not enough data}
- */
-IcmpPacket::ReadReturnCode Icmpv6Packet::read( istream &is )
-{
-    if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-
-#ifdef IPV6_DATA_PRESENT_IN_ISTREAM
-    //TODO WHY IPv6 does not come like IPv4????
-    // try to read ip header
-    is >> IpHeader;
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-#endif
-
-    // try to read the icmp header
-    is >> IcmpPayloadHeader;
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-
-    // calculate the size of the ICMP data
-    streamsize data_length = static_cast<streamsize>( IpHeader.get_payload_length() )
-                           - static_cast<streamsize>( IcmpPayloadHeader.get_header_length() );
-
-    // try to read that amount of data
-    if ( data_length < 0 )
-    {
-        GlobalLogger.error() << "Invalid size for optional ICMP data: "
-                             << data_length << endl;
-        is.setstate( ios::failbit );
-        return IcmpPacket::ReadReturnCode_INVALID_SIZE;
-    }
-    else if ( data_length > 0 )
-    {
-        size_t options_size = static_cast<size_t>( data_length );
-        scoped_array<uint8_t> scoped_data( new uint8_t[options_size+1] ); // need a 0 after data
-        memset(scoped_data.get(), 0, (options_size+1)*sizeof(uint8_t));
-        char *char_data = reinterpret_cast<char *>( scoped_data.get() );
-
-        (void) is.read( char_data, data_length );    // leave 0 at the end
-        IcmpPayloadData = char_data;  // implicit cast
-    }
-
-    if ( is.eof() )
-        return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
-    else if ( !is.good() )
-        return IcmpPacket::ReadReturnCode_BAD_STREAM;
-    else
-        return IcmpPacket::ReadReturnCode_OK;
-}
-
-/**
- * @brief Write the ICMP packet to the @c ostream.
- *
- * @param os The output stream.
- *
- * @return @c true if the write was successful, or @c false if an error occurred.
- */
-bool Icmpv6Packet::write( std::ostream &os ) const
-{
-    os.clear();
-
-    os << IcmpPayloadHeader << IcmpPayloadData;
-
-    return !os.fail();
-}
-
diff --git a/src/icmp/icmpv6packet.h b/src/icmp/icmpv6packet.h
deleted file mode 100644 (file)
index 0947398..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff
-// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
-//
-// Distributed under the Boost Software License, Version 1.0.
-//    (See accompanying file LICENSE_1_0.txt or copy at
-//          http://www.boost.org/LICENSE_1_0.txt)
-#ifndef ICMPV6_PACKET_H
-#define ICMPV6_PACKET_H
-
-#include <stdint.h>
-
-#include <istream>
-#include <ostream>
-
-#include <boost/asio.hpp>
-
-#include "icmp/icmppacket.h"
-#include "icmp/icmpv6header.h"
-#include "icmp/icmpdata.h"
-#include "icmp/icmptype.h"
-#include "ip/ipv6header.h"
-
-//-----------------------------------------------------------------------------
-// Icmpv6Packet
-//-----------------------------------------------------------------------------
-
-/**
- * @brief This class represents the ICMP version 6 Packet.
- *
- * The ICMP Packet format is:
- *
- * @code
- * 0      3 4            11 12   15 16          23 24            31
- * +-------+---------------+--------------------------------------+      ---
- * |       |               |                                      |       ^
- * |version| traffic class |              flow label              |       |
- * |  (6)  |               |                                      |       |
- * +-------+---------------+-------+--------------+---------------+       |
- * |                               |              |               |       |
- * |        payload length         | next header  |   hop limit   |       |
- * |                               |              |               |       |
- * +---------------+---------------+--------------+---------------+       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                      source IPv6 address                     | IPv6 Header
- * |                                                              |   40 bytes
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * +--------------------------------------------------------------+       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                   destination IPv6 address                   |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       |
- * |                                                              |       v
- * +---------------+---------------+------------------------------+      ---
- * |               |               |                              |       ^
- * |     type      |     code      |          checksum            |       |
- * |               |               |                              |       |
- * +---------------+---------------+------------------------------+       |
- * |                               |                              | ICMP Payload
- * |          identifier           |       sequence number        | (header +
- * |                               |                              |       data)
- * +-------------------------------+------------------------------+   8+ bytes
- * |                                                              |       |
- * |                      data (optional)                         |       |
- * |                                                              |       v
- * +-------------------------------+------------------------------+      ---
- * @endcode
- */
-class Icmpv6Packet : public IcmpPacket
-{
-public:
-    Icmpv6Packet();
-    Icmpv6Packet(
-            const Icmpv6Header &icmp_header,
-            const IcmpData &icmp_data
-    );
-    virtual ~Icmpv6Packet();
-
-    Ipv6Header get_ip_header() const;
-    Icmpv6Header get_icmp_header() const;
-    IcmpData get_icmp_data() const;
-
-    virtual bool match_echo_reply(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-    virtual bool match_destination_unreachable(
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-
-    virtual void print_echo_reply(
-            const std::size_t &bytes_transferred,
-            const boost::posix_time::ptime &time_packet_sent
-    ) const;
-    virtual void print_destination_unreachable() const;
-
-    virtual ReadReturnCode read( std::istream &is );
-    bool write( std::ostream &os ) const;
-
-
-private:
-    bool match(
-            const Icmpv6Type type,
-            const uint16_t identifier,
-            const uint16_t sequence_number,
-            const boost::asio::ip::address &source_address
-    ) const;
-
-private:
-    /// The IP header.
-    Ipv6Header IpHeader;
-    /// The ICMP packet header.
-    Icmpv6Header IcmpPayloadHeader;
-    /// The ICMP packet payload (data).
-    IcmpData IcmpPayloadData;
-};
-
-#endif // ICMPV6_PACKET_H