fixed bug in match_destination_unreachable: message does not have to come from origin...
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 19 Mar 2015 17:30:00 +0000 (18:30 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 19 Mar 2015 17:30:00 +0000 (18:30 +0100)
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

src/icmp/icmpdata.cpp
src/icmp/icmpdata.h
src/icmp/icmpdestinationunreachabledata.cpp
src/icmp/icmpdestinationunreachabledata.h
src/icmp/icmpechodata.cpp
src/icmp/icmpechodata.h
src/icmp/icmppacket.cpp
src/icmp/icmptimeexceededdata.cpp
src/icmp/icmptimeexceededdata.h
test/CMakeLists.test_icmpv4header.txt
test/CMakeLists.test_icmpv6header.txt

index 674f1d8..3e54173 100644 (file)
 #include "icmpdata.h"
 
 #include <sstream>
+#include <iostream>
+
+#include <logfunc.hpp>
+
+#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();  }
 
index 4ac3157..3b25064 100644 (file)
 #include <iostream>
 #include <boost/shared_ptr.hpp>
 #include <boost/date_time/posix_time/ptime.hpp>
+#include <boost/asio/ip/address.hpp>
 #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;
 
index a01595c..825697e 100644 (file)
@@ -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(
index 876ab67..0f49fb3 100644 (file)
@@ -30,6 +30,8 @@
 #include <boost/date_time/posix_time/ptime.hpp>
 #include "icmp/icmpdata_pingfailreply.h"
 
+#include <boost/asio/ip/address.hpp>
+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;
index f6c7ae3..a520249 100644 (file)
@@ -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; }
 
 
index ac73adb..d408e44 100644 (file)
@@ -29,6 +29,9 @@
 #include "icmp/icmpdata.h"
 
 #include <boost/date_time/posix_time/ptime.hpp>
+#include <boost/asio/ip/address.hpp>
+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;
index b5e76de..ab6e682 100644 (file)
@@ -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,
index b1ef2d5..8f2af93 100644 (file)
@@ -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(
index 5f2fc1a..45b73c1 100644 (file)
@@ -30,6 +30,8 @@
 #include <boost/date_time/posix_time/ptime.hpp>
 #include "icmp/icmpdata_pingfailreply.h"
 
+#include <boost/asio/ip/address.hpp>
+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;
index 1133e30..9ac5c9f 100644 (file)
@@ -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
index f54dd5c..5a5a787 100644 (file)
@@ -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