From: Christian Herdtweck Date: Thu, 19 Mar 2015 17:30:00 +0000 (+0100) Subject: fixed bug in match_destination_unreachable: message does not have to come from origin... X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=81c265174b87bf78b8f71b6b2959e1b78f338992;p=pingcheck fixed bug in match_destination_unreachable: message does not have to come from original destination that means we have to interpret the ip header within the icmp data, which is done by converting IcmpData::raw_data to a stream which is fed to IpvXHeader.read Also means that address to test for has to be forwarded to IcmpDestinationUnreachableData and cannot be simply tested in IcmpData already --> change function prototype in all IcmpData classes --- diff --git a/src/icmp/icmpdata.cpp b/src/icmp/icmpdata.cpp index 674f1d8..3e54173 100644 --- a/src/icmp/icmpdata.cpp +++ b/src/icmp/icmpdata.cpp @@ -25,6 +25,16 @@ #include "icmpdata.h" #include +#include + +#include + +#include "boost_assert_handler.h" +#include "ip/ipv4header.h" +#include "ip/ipv6header.h" + +using I2n::Logger::GlobalLogger; +using boost::asio::ip::address; IcmpData::IcmpData() : size( 0 ) @@ -41,7 +51,8 @@ bool IcmpData::match_echo_reply(const uint16_t identifier, { return false; } bool IcmpData::match_destination_unreachable(const uint16_t identifier, - const uint16_t sequence_number) const + const uint16_t sequence_number, + const address &destination_address) const { return false; } bool IcmpData::match_time_exceeded(const uint16_t identifier, @@ -59,6 +70,42 @@ int IcmpData::get_ip_version() const return version; } +IpHeaderPtr IcmpData::get_ip_header() const +{ + // make stream from relevant part of payload + std::stringbuf buffer; + std::ostream buf_filler( &buffer ); + raw_data.write( buf_filler ); + std::istream stream( &buffer ); + + // skip 4 byte + stream.seekg(4, stream.beg); + + // interpret as IP header + int ip_version = get_ip_version(); + IpHeaderPtr result; + if (ip_version == 4) + { + Ipv4Header *result_val = new Ipv4Header(); + stream >> *result_val; + result.reset( result_val ); + } + else if (ip_version == 6) + { + Ipv6Header *result_val = new Ipv6Header(); + stream >> *result_val; + result.reset( result_val ); + } + else + { // throw runtime error through boost_assert_handler + GlobalLogger.error() << "Invalid IP version: " << ip_version + << " ! Maybe data is no IP packet?"; + BOOST_ASSERT( !"Invalid IP version or not IP packet!" ); + } + + return result; +} + uint32_t IcmpData::calc_checksum_part() const { return raw_data.calc_checksum_part(); } diff --git a/src/icmp/icmpdata.h b/src/icmp/icmpdata.h index 4ac3157..3b25064 100644 --- a/src/icmp/icmpdata.h +++ b/src/icmp/icmpdata.h @@ -29,7 +29,11 @@ #include #include #include +#include #include "host/messagepayload.h" +#include "ip/ipheader.h" + +using boost::asio::ip::address; /** @brief contents of ICMP packets after the first 4 bytes of the ICMP header * used for ICMPv4 and ICMPv6 @@ -50,7 +54,8 @@ public: const uint16_t sequence_number) const; virtual bool match_destination_unreachable(const uint16_t identifier, - const uint16_t sequence_number) const; + const uint16_t sequence_number, + const address &destination_address) const; virtual bool match_time_exceeded(const uint16_t identifier, const uint16_t sequence_number) const; @@ -58,6 +63,8 @@ public: // including 4 bytes from ICMPv4 header std::size_t get_size() const; + IpHeaderPtr get_ip_header() const; + uint32_t calc_checksum_part() const; int get_ip_version() const; diff --git a/src/icmp/icmpdestinationunreachabledata.cpp b/src/icmp/icmpdestinationunreachabledata.cpp index a01595c..825697e 100644 --- a/src/icmp/icmpdestinationunreachabledata.cpp +++ b/src/icmp/icmpdestinationunreachabledata.cpp @@ -34,11 +34,14 @@ IcmpDestinationUnreachableData::IcmpDestinationUnreachableData( {} bool IcmpDestinationUnreachableData::match_destination_unreachable( - const uint16_t identifier, - const uint16_t sequence_number) const + const uint16_t identifier, + const uint16_t sequence_number, + const address &destination_address) const { return IcmpData_PingFailReply::match_ping_request(identifier, - sequence_number); + sequence_number) + && IcmpData::get_ip_header()->get_destination_address() + == destination_address; } bool IcmpDestinationUnreachableData::match_time_exceeded( diff --git a/src/icmp/icmpdestinationunreachabledata.h b/src/icmp/icmpdestinationunreachabledata.h index 876ab67..0f49fb3 100644 --- a/src/icmp/icmpdestinationunreachabledata.h +++ b/src/icmp/icmpdestinationunreachabledata.h @@ -30,6 +30,8 @@ #include #include "icmp/icmpdata_pingfailreply.h" +#include +using boost::asio::ip::address; /** * Data for a DestinationUnreachableMessage @@ -43,7 +45,8 @@ public: IcmpDestinationUnreachableData(const std::size_t size_arg); bool match_destination_unreachable(const uint16_t identifier, - const uint16_t sequence_number) const; + const uint16_t sequence_number, + const address &destination_address) const; bool match_time_exceeded(const uint16_t identifier, const uint16_t sequence_number) const; diff --git a/src/icmp/icmpechodata.cpp b/src/icmp/icmpechodata.cpp index f6c7ae3..a520249 100644 --- a/src/icmp/icmpechodata.cpp +++ b/src/icmp/icmpechodata.cpp @@ -50,7 +50,8 @@ IcmpEchoData::IcmpEchoData(const std::size_t size_arg) bool IcmpEchoData::match_destination_unreachable( const uint16_t identifier, - const uint16_t sequence_number) const + const uint16_t sequence_number, + const address &destination_address) const { return false; } diff --git a/src/icmp/icmpechodata.h b/src/icmp/icmpechodata.h index ac73adb..d408e44 100644 --- a/src/icmp/icmpechodata.h +++ b/src/icmp/icmpechodata.h @@ -29,6 +29,9 @@ #include "icmp/icmpdata.h" #include +#include +using boost::asio::ip::address; + /** @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,7 +47,8 @@ public: IcmpEchoData(const std::size_t size_arg); bool match_destination_unreachable(const uint16_t identifier, - const uint16_t sequence_number) const; + const uint16_t sequence_number, + const address &destination_address) const; bool match_echo_reply(const uint16_t identifier, const uint16_t sequence_number) const; diff --git a/src/icmp/icmppacket.cpp b/src/icmp/icmppacket.cpp index b5e76de..ab6e682 100644 --- a/src/icmp/icmppacket.cpp +++ b/src/icmp/icmppacket.cpp @@ -124,9 +124,9 @@ 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); + return icmp_data_ptr->match_destination_unreachable(identifier, + sequence_number, + destination_address); } bool IcmpPacket::match_time_exceeded(const uint16_t identifier, diff --git a/src/icmp/icmptimeexceededdata.cpp b/src/icmp/icmptimeexceededdata.cpp index b1ef2d5..8f2af93 100644 --- a/src/icmp/icmptimeexceededdata.cpp +++ b/src/icmp/icmptimeexceededdata.cpp @@ -41,8 +41,9 @@ bool IcmpTimeExceededData::match_time_exceeded( } bool IcmpTimeExceededData::match_destination_unreachable( - const uint16_t identifier, - const uint16_t sequence_number) const + const uint16_t identifier, + const uint16_t sequence_number, + const address &destination_address) const { return false; } void IcmpTimeExceededData::print( diff --git a/src/icmp/icmptimeexceededdata.h b/src/icmp/icmptimeexceededdata.h index 5f2fc1a..45b73c1 100644 --- a/src/icmp/icmptimeexceededdata.h +++ b/src/icmp/icmptimeexceededdata.h @@ -30,6 +30,8 @@ #include #include "icmp/icmpdata_pingfailreply.h" +#include +using boost::asio::ip::address; /** * Data for a DestinationUnreachableMessage @@ -43,7 +45,8 @@ public: IcmpTimeExceededData(const std::size_t size_arg); bool match_destination_unreachable(const uint16_t identifier, - const uint16_t sequence_number) const; + const uint16_t sequence_number, + const address &destination_address) const; bool match_time_exceeded(const uint16_t identifier, const uint16_t sequence_number) const; diff --git a/test/CMakeLists.test_icmpv4header.txt b/test/CMakeLists.test_icmpv4header.txt index 1133e30..9ac5c9f 100644 --- a/test/CMakeLists.test_icmpv4header.txt +++ b/test/CMakeLists.test_icmpv4header.txt @@ -2,6 +2,9 @@ add_executable(test_icmpv4header test_icmpv4header.cpp ${CMAKE_SOURCE_DIR}/src/boost_assert_handler.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipheader.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipv4header.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipv6header.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata_pingfailreply.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpechodata.cpp diff --git a/test/CMakeLists.test_icmpv6header.txt b/test/CMakeLists.test_icmpv6header.txt index f54dd5c..5a5a787 100644 --- a/test/CMakeLists.test_icmpv6header.txt +++ b/test/CMakeLists.test_icmpv6header.txt @@ -2,6 +2,9 @@ add_executable(test_icmpv6header test_icmpv6header.cpp ${CMAKE_SOURCE_DIR}/src/boost_assert_handler.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipheader.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipv4header.cpp + ${CMAKE_SOURCE_DIR}/src/ip/ipv6header.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpdata_pingfailreply.cpp ${CMAKE_SOURCE_DIR}/src/icmp/icmpechodata.cpp