diff --git a/src/IPacketHandler.h b/src/IPacketHandler.h index dc77f25..e5f5b14 100644 --- a/src/IPacketHandler.h +++ b/src/IPacketHandler.h @@ -2,7 +2,7 @@ #define IPACKETHANDLER_H #include "Main_t.h" - +#include "IPacketHandler_t.h" namespace Tins { class PDU; diff --git a/src/IPacketHandler_t.h b/src/IPacketHandler_t.h index 334830c..3697bd3 100644 --- a/src/IPacketHandler_t.h +++ b/src/IPacketHandler_t.h @@ -7,6 +7,7 @@ interface IPacketHandler; typedef std::shared_ptr SPtrIPacketHandler; +typedef std::unique_ptr UPtrIPacketHandler; typedef std::list SPtrIPacketHandlerList; #endif // ABSTRACTPACKETHANDLER_T_H_INCLUDED diff --git a/src/Icmp4ToIcmp6PacketHandler.cpp b/src/Icmp4ToIcmp6PacketHandler.cpp new file mode 100644 index 0000000..d73fdb1 --- /dev/null +++ b/src/Icmp4ToIcmp6PacketHandler.cpp @@ -0,0 +1,57 @@ +#include "Icmp4ToIcmp6PacketHandler.h" +#include +#include +#include + +Icmp4ToIcmp6PacketHandler::Icmp4ToIcmp6PacketHandler(const Tins::IPv6Address & newPrefix) : Ip4ToIp6PacketHandler(newPrefix) +{ +} + +Icmp4ToIcmp6PacketHandler::~Icmp4ToIcmp6PacketHandler() +{ +} + +bool Icmp4ToIcmp6PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler) +{ + // callback handvet requeried + if (callBackHandler == nullptr) + { + return false; + } + + // get ipv4 packet + const Tins::ICMP * icmpv4Pdu = pdu.find_pdu(); + if(icmpv4Pdu == nullptr) + { + return false; + } + + // create icmp6 pdu + const Tins::ICMP::Flags type = icmpv4Pdu->type(); + std::unique_ptr icmpv6Pdu; + switch (type) { + case Tins::ICMP::Flags::ECHO_REPLY: + icmpv6Pdu = std::make_unique(Tins::ICMPv6::ECHO_REQUEST); + break; + case Tins::ICMP::Flags::ECHO_REQUEST: + icmpv6Pdu = std::make_unique(Tins::ICMPv6::ECHO_REPLY); + break; + default: + return false; + } + + icmpv6Pdu->identifier(icmpv4Pdu->id()); + icmpv6Pdu->sequence(icmpv4Pdu->sequence()); + icmpv6Pdu->code(0); + + // replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler + const Tins::IP * ipPdu = pdu.find_pdu(); + if(ipPdu == nullptr) + { + return false; + } + + Tins::IP * cloneIpPdu = ipPdu->clone(); + cloneIpPdu->inner_pdu(*icmpv6Pdu); + return Ip4ToIp6PacketHandler::handle(*cloneIpPdu, callBackHandler); +} diff --git a/src/Icmp4ToIcmp6PacketHandler.h b/src/Icmp4ToIcmp6PacketHandler.h new file mode 100644 index 0000000..ac2c853 --- /dev/null +++ b/src/Icmp4ToIcmp6PacketHandler.h @@ -0,0 +1,15 @@ +#ifndef ICMP4TOICMP6PACKETHANDLER_H +#define ICMP4TOICMP6PACKETHANDLER_H + +#include "Ip4ToIp6PacketHandler.h" + +class Icmp4ToIcmp6PacketHandler : public Ip4ToIp6PacketHandler +{ +public: + + Icmp4ToIcmp6PacketHandler(const Tins::IPv6Address & prefix); + virtual ~Icmp4ToIcmp6PacketHandler(); + + virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override; +}; +#endif diff --git a/src/Icmp6ToIcmp4PacketHandler.cpp b/src/Icmp6ToIcmp4PacketHandler.cpp new file mode 100644 index 0000000..af2500c --- /dev/null +++ b/src/Icmp6ToIcmp4PacketHandler.cpp @@ -0,0 +1,62 @@ +#include "Icmp6ToIcmp4PacketHandler.h" +#include +#include +#include +#include "NdpToArpPacketHandler.h" + +Icmp6ToIcmp4PacketHandler::Icmp6ToIcmp4PacketHandler() : Ip6ToIp4PacketHandler() +{ + ndpToArpHandler = std::make_unique(); +} + +Icmp6ToIcmp4PacketHandler::~Icmp6ToIcmp4PacketHandler() +{ +} + +bool Icmp6ToIcmp4PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler) +{ + // callback handvet requeried + if (callBackHandler == nullptr) + { + return false; + } + + // get icmpv6 packet + const Tins::ICMPv6 * icmpv6Pdu = pdu.find_pdu(); + if(icmpv6Pdu == nullptr) + { + return false; + } + + // create icmp6 pdu + const Tins::ICMPv6::Types type = icmpv6Pdu->type(); + std::unique_ptr icmpv4Pdu; + switch (type) { + case Tins::ICMPv6::ECHO_REPLY: + icmpv4Pdu = std::make_unique(Tins::ICMP::Flags::ECHO_REQUEST); + break; + case Tins::ICMPv6::ECHO_REQUEST: + icmpv4Pdu = std::make_unique(Tins::ICMP::Flags::ECHO_REPLY); + break; + case Tins::ICMPv6::NEIGHBOUR_SOLICIT: + case Tins::ICMPv6::NEIGHBOUR_ADVERT: + return ndpToArpHandler->handle(pdu, callBackHandler); + default: + return false; + } + + icmpv4Pdu->id(icmpv6Pdu->identifier()); + icmpv4Pdu->sequence(icmpv6Pdu->sequence()); + icmpv4Pdu->code(0); + + // replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler + const Tins::IPv6 * ipv6Pdu = pdu.find_pdu(); + if(ipv6Pdu == nullptr) + { + return false; + } + + Tins::IPv6 * cloneIpv6Pdu = ipv6Pdu->clone(); + cloneIpv6Pdu->inner_pdu(*icmpv4Pdu); + return Ip6ToIp4PacketHandler::handle(*cloneIpv6Pdu, callBackHandler); +} diff --git a/src/Icmp6ToIcmp4PacketHandler.h b/src/Icmp6ToIcmp4PacketHandler.h new file mode 100644 index 0000000..ae2fd78 --- /dev/null +++ b/src/Icmp6ToIcmp4PacketHandler.h @@ -0,0 +1,17 @@ +#ifndef ICMP6TOICMP4PACKETHANDLER_H +#define ICMP6TOICMP4PACKETHANDLER_H + +#include "Ip6ToIp4PacketHandler.h" + +class Icmp6ToIcmp4PacketHandler : public Ip6ToIp4PacketHandler +{ +public: + + Icmp6ToIcmp4PacketHandler(); + virtual ~Icmp6ToIcmp4PacketHandler(); + + virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override; +private: + UPtrIPacketHandler ndpToArpHandler; +}; +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0f3a1a9..9026cd5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,6 +5,10 @@ else () set (CMAKE_CXX_STANDARD 11) endif () +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif(COMMAND cmake_policy) + project(test_1261nat) set(CMAKE_BUILD_TYPE Debug)