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)
#include <stdint.h>
#include <iostream>
+#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include "host/messagepayload.h"
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)
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)
<< " 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
#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
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;
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;
};
#include "icmp/icmppacket.h"
#include <iostream>
+#include <sstream>
#include <boost/scoped_array.hpp>
#include <logfunc.hpp>
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();
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;
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 )
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)
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,
ReadReturnCode read(std::istream &is);
bool write(std::ostream &os) const;
+
+ std::string to_string() const;
};
typedef boost::shared_ptr<IcmpPacket> IcmpPacketItem;
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: "
// 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
IcmpPacketItem icmp_packet( new IcmpPacket( protocol,
icmp_header,
icmp_data ) );
+ GlobalLogger.debug() << "IcmpPacketFactory: created "
+ << icmp_packet->to_string() << std::endl;
return 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 ) )
}
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 )
virtual ~IpHeader() {}
+ virtual std::string to_string() const
+ { return "[IP header]"; }
};
typedef boost::shared_ptr<IpHeader> IpHeaderPtr;
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);
}
/**
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);
}
/**
}
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 );
}
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 )
signal_data.stopped = true;
break;
}
+ GlobalLogger.info() << "continuing io_service main loop" << endl;
}
}