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