now working again: creating echo requests and parsing replies
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 12 Mar 2015 14:51:58 +0000 (15:51 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 12 Mar 2015 14:51:58 +0000 (15:51 +0100)
also:
* created a to_string method for easier output
* in constructors of IP headers set version right away
* compare that version to the one received in IcmpPacket::read

12 files changed:
src/host/messagepayload.cpp
src/icmp/icmpdata.h
src/icmp/icmpechodata.h
src/icmp/icmpheader.h
src/icmp/icmppacket.cpp
src/icmp/icmppacket.h
src/icmp/icmppacketfactory.cpp
src/icmp/icmppinger.cpp
src/ip/ipheader.h
src/ip/ipv4header.cpp
src/ip/ipv6header.cpp
src/main.cpp

index c095c8e..4e931ce 100644 (file)
@@ -398,7 +398,7 @@ void MessagePayload::encode_string( const int first_byte_index,
     BOOST_ASSERT( 0 < PayloadSizeInBytes );
     BOOST_ASSERT( Payload.capacity() == PayloadSizeInBytes );
     BOOST_ASSERT( ( 0 <= first_byte_index ) && ( first_byte_index < static_cast<int>(PayloadSizeInBytes) ) );
-    BOOST_ASSERT( first_byte_index +length < static_cast<int>(PayloadSizeInBytes) );
+    BOOST_ASSERT( first_byte_index +length <= static_cast<int>(PayloadSizeInBytes) );
 
     const uint8_t *data_converted = reinterpret_cast<const uint8_t *>(&value[0]);
     for (int index=0; index<length; ++index)
index dcb8586..b65cae9 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <stdint.h>
 #include <iostream>
+#include <sstream>
 #include <boost/shared_ptr.hpp>
 #include <boost/date_time/posix_time/ptime.hpp>
 #include "host/messagepayload.h"
@@ -70,6 +71,13 @@ public:
                         const uint32_t ttl) const
     {}
 
+    virtual std::string to_string() const
+    {
+        std::stringstream buf;
+        buf << "[IcmpData of length " << size << "]";
+        return buf.str();
+    }
+
 protected:
 
     IcmpData(const std::size_t size_arg)
index ae31517..324b82c 100644 (file)
@@ -45,11 +45,12 @@ class IcmpEchoData : public IcmpData
 public:
     IcmpEchoData(const uint16_t identifier, const uint16_t sequence_number,
                  const std::string &optional_data)
-        : IcmpData(12)
+        : IcmpData( 4 + optional_data.length() )
     {
         IcmpData::raw_data.encode16(0, 1, identifier);
         IcmpData::raw_data.encode16(2, 3, sequence_number);
         IcmpData::raw_data.encode_string(4, optional_data);
+        GlobalLogger.debug() << "Done creating echo request" << std::endl;
     }
 
     IcmpEchoData(const std::size_t size_arg)
@@ -95,6 +96,17 @@ public:
              << " time=" << elapsed_time << " ms" << std::endl;
     }
 
+    std::string to_string() const
+    {
+        std::stringstream buf;
+        buf << "[EchoData ID=" << std::showbase << std::hex << get_identifier()
+            << ",seq.nr=" << std::noshowbase << std::dec<< get_sequence_number()
+            << ",data of size " << IcmpData::size-4;
+        //for (int idx=4; idx < IcmpData::size; ++idx)
+        //    buf << IcmpData::raw_data[idx];
+        buf << "]";
+        return buf.str();
+    }
 };
 
 #endif
index b9922d9..98d02fa 100644 (file)
 
 #include <stdint.h>
 #include <iostream>
+#include <sstream>
 #include <boost/scoped_array.hpp>
 
+#include <logfunc.hpp>
+using I2n::Logger::GlobalLogger;
+
 /** @brief first 4 byte of ICMP header (v4 and v6)
  *
  * In ICMP v4, the first 4 bytes are standardized, the other 4 depend on
@@ -77,10 +81,11 @@ public:
         checksum = static_cast<uint16_t>( ~sum );
     }
 
-    bool write(std::ostream &os) const
+    std::ostream& write(std::ostream &os) const
     {
-        os << type << code << checksum;
-        return os.good();
+        uint8_t checksum_lsb = static_cast<uint8_t>(checksum & 0x00FF);
+        uint8_t checksum_msb = static_cast<uint8_t>((checksum & 0xFF00) >> 8);
+        os << type << code << checksum_msb << checksum_lsb;
     }
 
     // returns the amount of data represented by this class;
@@ -88,10 +93,19 @@ public:
     uint16_t get_header_length() const
     {    return 4;   }
 
+    std::string to_string() const
+    {
+        std::stringstream buf;
+        buf << "[Icmp header type=" << static_cast<int>(type)
+            << ",code=" << static_cast<int>(code)
+            << " (cksum:" << std::showbase << std::hex << checksum << ")]";
+        return buf.str();
+    }
+
 protected:
     uint8_t type;
     uint8_t code;
-    uint16_t checksum;   // to be used in check_integrity
+    uint16_t checksum;
 };
 
 
index f92bdec..5862e65 100644 (file)
@@ -23,6 +23,7 @@
 #include "icmp/icmppacket.h"
 
 #include <iostream>
+#include <sstream>
 #include <boost/scoped_array.hpp>
 
 #include <logfunc.hpp>
@@ -47,7 +48,17 @@ IcmpPacket::ReadReturnCode IcmpPacket::read( std::istream &is )
         return IcmpPacket::ReadReturnCode_BAD_STREAM;
 
     // try to read ip header
-    uint8_t version = static_cast<uint8_t>( is.peek() );
+    uint8_t version_with_ihl = static_cast<uint8_t>( is.peek() );
+    uint8_t version = (version_with_ihl & 0xF0) >> 4;
+
+    if ( version != ip_head_ptr->get_version() )
+    {
+        GlobalLogger.error() << "IP version given to constructor ("
+            << static_cast<int>(ip_head_ptr->get_version()) << ") does not "
+            << "match the on in input stream (" << static_cast<int>(version)
+            << ")!" << std::endl;
+        BOOST_ASSERT( !"Inconsistent IP version!" );
+    }
     if (version == 4)
     {
         Ipv4Header *new_header = new Ipv4Header();
@@ -60,8 +71,12 @@ IcmpPacket::ReadReturnCode IcmpPacket::read( std::istream &is )
         is >> *new_header;
         ip_head_ptr.reset( new_header );
     }
-    else    // pingcheck-type error throwing
+    else
+    {   // pingcheck-type error throwing
+        GlobalLogger.error() << "Invalid IP version: "
+                             << static_cast<int>(version) << "!" << std::endl;
         BOOST_ASSERT( !"Invalid IP version!" );
+    }
 
     if ( is.eof() )
         return IcmpPacket::ReadReturnCode_NOT_ENOUGH_DATA;
@@ -77,9 +92,10 @@ IcmpPacket::ReadReturnCode IcmpPacket::read( std::istream &is )
         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() );
+    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 )
@@ -184,4 +200,17 @@ std::ostream& operator<<(
     return os;
 }
 
+
+std::string IcmpPacket::to_string() const
+{
+    std::stringstream buf;
+    buf << "[IcmpPacket: ";
+    buf << ip_head_ptr->to_string() << ", ";
+    buf << icmp_header.to_string() << ", ";
+    buf << icmp_data_ptr->to_string();
+    buf << "]";
+    return buf.str();
+}
+
+
 // (created using vim -- the world's best text editor)
index d726ca5..c2d0389 100644 (file)
@@ -63,11 +63,18 @@ public:
 
     static std::string return_code_to_string( const ReadReturnCode &code );
 
-    IcmpPacket()
+    IcmpPacket(const icmp::socket::protocol_type &protocol)
         : ip_head_ptr()
         , icmp_header()
         , icmp_data_ptr()
-    {}
+    {
+        if ( icmp::v4() == protocol )
+            ip_head_ptr.reset( new Ipv4Header() );
+        else if ( icmp::v6() == protocol )
+            ip_head_ptr.reset( new Ipv6Header() );
+        else  // pingcheck-type throwing of exceptions:
+            BOOST_ASSERT( !"Invalid IP version, need 4 or 6!" );
+    }
 
     // IP header is created with only 0s, is not used in write, anyway
     IcmpPacket(const icmp::socket::protocol_type &protocol,
@@ -148,6 +155,8 @@ public:
     ReadReturnCode read(std::istream &is);
 
     bool write(std::ostream &os) const;
+
+    std::string to_string() const;
 };
 
 typedef boost::shared_ptr<IcmpPacket> IcmpPacketItem;
index ddfd9fe..1b4ccf4 100644 (file)
@@ -143,7 +143,7 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
     IcmpPacketItem icmp_packet;
 
     if ( icmp::v4() == protocol || icmp::v6() == protocol )
-        icmp_packet.reset( new IcmpPacket() );
+        icmp_packet.reset( new IcmpPacket( protocol ) );
     else
     {
         GlobalLogger.warning() << "ICMP packet creation failed: "
@@ -163,9 +163,6 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
         // read all data into backup
         ostream backup_filler(&data_backup);
         backup_filler << is.rdbuf();
-        //GlobalLogger.debug() << "Copied ICMP raw data ("
-        //     << data_backup.str().size();
-        //     << " bytes) for dumping in case of broken packet" << endl;
 
         // create a new stream from backup buffer
         //   and use that in read
@@ -231,6 +228,8 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet_echo_request(
     IcmpPacketItem icmp_packet( new IcmpPacket( protocol,
                                                 icmp_header,
                                                 icmp_data ) );
+    GlobalLogger.debug() << "IcmpPacketFactory: created "
+                         << icmp_packet->to_string() << std::endl;
 
     return icmp_packet;
 }
index 496738e..5837062 100644 (file)
@@ -211,6 +211,7 @@ bool IcmpPinger::send_echo_request( const IcmpPacketItem icmp_packet )
                     << DestinationEndpoint.address().to_string()
                     << ": sending ping" << endl;
         const_buffers_1 data = request_buffer.data();
+
         // Block until send the data
         bytes_sent = PacketDistributor->get_socket()->send_to( data, DestinationEndpoint );
         if ( bytes_sent != buffer_size( data ) )
@@ -512,6 +513,9 @@ void IcmpPacketDistributor::handle_receive(
         }
         else
         {
+            GlobalLogger.debug() << "Succesfully parsed ICMP packet"
+                                 << std::endl;
+
             // check which pinger wants this packet
             bool packet_matches = false;
             BOOST_FOREACH( const IcmpPingerItem &pinger, PingerList )
index 1fff074..a103884 100644 (file)
@@ -43,6 +43,8 @@ public:
 
     virtual ~IpHeader() {}
 
+    virtual std::string to_string() const
+    {   return "[IP header]";  }
 };
 
 typedef boost::shared_ptr<IpHeader> IpHeaderPtr;
index 299b4e4..a4649ab 100644 (file)
@@ -28,6 +28,11 @@ static const size_t Ipv4HeaderSizeInBytes_withoutOptions = 20;
 Ipv4Header::Ipv4Header() :
     Payload( Ipv4HeaderSizeInBytes_withoutOptions )
 {
+    // encode a 4 into the first 4 bits
+    Payload.encode1(0, 0, 0);
+    Payload.encode1(0, 1, 1);
+    Payload.encode1(0, 2, 0);
+    Payload.encode1(0, 3, 0);
 }
 
 /**
index ca03580..4faa518 100644 (file)
@@ -28,6 +28,11 @@ static const size_t Ipv6HeaderSizeInBytes = 40;
 Ipv6Header::Ipv6Header() :
     Payload( Ipv6HeaderSizeInBytes )
 {
+    // encode a 6 into the first 4 bits
+    Payload.encode1(0, 0, 0);
+    Payload.encode1(0, 1, 1);
+    Payload.encode1(0, 2, 1);
+    Payload.encode1(0, 3, 0);
 }
 
 /**
index 003622b..2f6be63 100644 (file)
@@ -390,7 +390,6 @@ void signal_checker( const boost::system::error_code &error )
     }
     else
     {   // re-schedule timer
-        GlobalLogger.debug() << "Setting another signal timer" << endl;
         signal_data.check_timer->expires_from_now( SIGNAL_CHECK_INTERVAL );
         signal_data.check_timer->async_wait( signal_checker );
     }
@@ -522,12 +521,12 @@ int main( int argc, const char *argv[] )
 
     if ( ret_code == 0 )
     {
+        GlobalLogger.info() << "starting io_service main loop" << endl;
         // call boost::asio main event loop, catching exceptions
         while ( !signal_data.stopped )
         {
             try
             {
-                GlobalLogger.info() << "starting/continuing io_service main loop" << endl;
                 io_service->run();
             }
             catch ( const std::exception &ex )
@@ -547,6 +546,7 @@ int main( int argc, const char *argv[] )
                 signal_data.stopped = true;
                 break;
             }
+            GlobalLogger.info() << "continuing io_service main loop" << endl;
         }
     }