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
#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 )
{ 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,
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(); }
#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
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;
// 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;
{}
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(
#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
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;
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; }
#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
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;
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,
}
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(
#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
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;
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
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