diff --git a/src/AbstractRouter.h b/src/AbstractRouter.h index ebeb7ba..c47116e 100644 --- a/src/AbstractRouter.h +++ b/src/AbstractRouter.h @@ -1,9 +1,9 @@ #ifndef ABSTRACTROUTER_H #define ABSTRACTROUTER_H -#include "INetworkInterfaceCard.h" +#include "IRouter.h" -class AbstractRouter: public INetworkInterfaceCard +class AbstractRouter: public IRouter { public: protected: diff --git a/src/ArpToNdpPacketHandler.cpp b/src/ArpToNdpPacketHandler.cpp new file mode 100644 index 0000000..c42d05d --- /dev/null +++ b/src/ArpToNdpPacketHandler.cpp @@ -0,0 +1,92 @@ +#include "ArpToNdpPacketHandler.h" +#include +#include +#include +#include +#include +#include +#include "IpAddressTranslator.h" + +ArpToNdpPacketHandler::ArpToNdpPacketHandler(const Tins::IPv6Address & newPrefix) +{ + prefix = std::make_unique(newPrefix); + ndpPrefix = std::make_unique("FF02:0:0:0:0:1:FF"); + ndpMask = std::make_unique("255.0.0.0"); +} + +ArpToNdpPacketHandler::~ArpToNdpPacketHandler() +{ +} + +bool ArpToNdpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler) +{ + // callback handvet requeried + if (callBackHandler == nullptr) + { + return false; + } + + // get ipv4 packet + const Tins::ARP * arpPdu = pdu.find_pdu(); + if(arpPdu == nullptr) + { + return false; + } + + // convert ipv4 addresses to ipv6 addresses + uint32_t ndpMaskField = *ndpMask; + uint32_t targetMaskield = arpPdu->target_ip_addr(); + uint32_t foo = ndpMaskField | targetMaskield; + UPtrIPv6Address srcIp6Address = std::make_unique(*prefix); + UPtrIPv6Address dstIp6Address = std::make_unique(*ndpPrefix); + UPtrIPv6Address targetIp6Address = std::make_unique(*prefix); + IpAddressTranslator::toIpv6Address(arpPdu->sender_ip_addr(), *srcIp6Address); + IpAddressTranslator::toIpv6Address(Tins::IPv4Address(foo), *dstIp6Address); + + // create ip4 pdu + std::unique_ptr ipv6Pdu = std::make_unique(*dstIp6Address,*srcIp6Address); + std::unique_ptr ndpPdu; + + switch (arpPdu->opcode()) + { + case Tins::ARP::REQUEST: + ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_SOLICIT); + break; + case Tins::ARP::REPLY: + ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_ADVERT); + break; + default: + return false; + } + + ndpPdu->target_addr(*targetIp6Address); + // create forwarding frame + std::unique_ptr ptrForwardEthPdu = std::make_unique(); + Tins::EthernetII & forwardEthPdu = *ptrForwardEthPdu; + + // copy src and dst mac address + const Tins::EthernetII * ethPdu = pdu.find_pdu(); + if(ethPdu != nullptr) + { + // @todo to set multicast + forwardEthPdu.src_addr(ethPdu->src_addr()); + forwardEthPdu.dst_addr(ethPdu->dst_addr()); + } + + forwardEthPdu /= *ipv6Pdu; + forwardEthPdu /= *ndpPdu; + + + // forward frame + return callBackHandler->handle(forwardEthPdu, this); +} + +const Tins::IPv6Address & ArpToNdpPacketHandler::getPrefix() const +{ + return *prefix; +} + +void ArpToNdpPacketHandler::setPrefix(const Tins::IPv6Address & newPrefix) +{ + *prefix = newPrefix; +} diff --git a/src/ArpToNdpPacketHandler.h b/src/ArpToNdpPacketHandler.h new file mode 100644 index 0000000..1fd0eb0 --- /dev/null +++ b/src/ArpToNdpPacketHandler.h @@ -0,0 +1,25 @@ +#ifndef ARPTONDPPACKETHANDLER_H +#define ARPTONDPPACKETHANDLER_H + +#include "AbstractPacketHandler.h" +#include "IPacketHandler_t.h" +#include "Ip6Packet_t.h" +#include "Ip4Packet_t.h" + +class ArpToNdpPacketHandler : public AbstractPacketHandler +{ +public: + + ArpToNdpPacketHandler(const Tins::IPv6Address & prefix); + virtual ~ArpToNdpPacketHandler(); + + virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override; + + const Tins::IPv6Address & getPrefix() const; + void setPrefix(const Tins::IPv6Address & newPrefix); +private: + UPtrIPv6Address prefix; + UPtrIPv6Address ndpPrefix; + UPtrIPv4Address ndpMask; +}; +#endif diff --git a/src/INetworkInterfaceCard_t.h b/src/INetworkInterfaceCard_t.h new file mode 100644 index 0000000..ce99f3c --- /dev/null +++ b/src/INetworkInterfaceCard_t.h @@ -0,0 +1,13 @@ +#ifndef INETWORKINTERFACECARD_T_H +#define INETWORKINTERFACECARD_T_H + + +#include +#include "Main_t.h" + +interface IPacketHandler; + + +interface INetworkInterfaceCard; +typedef std::shared_ptr SPtrINetworkInterfaceCard; +#endif diff --git a/src/Ip4Packet_t.h b/src/Ip4Packet_t.h new file mode 100644 index 0000000..dc0465f --- /dev/null +++ b/src/Ip4Packet_t.h @@ -0,0 +1,12 @@ +#ifndef IP4PACKET_T_H +#define IP4PACKET_T_H + +#include + +namespace Tins +{ + class IPv4Address; +} + +typedef std::unique_ptr UPtrIPv4Address; +#endif diff --git a/src/Ip6Packet_t.h b/src/Ip6Packet_t.h index f223039..d41f734 100644 --- a/src/Ip6Packet_t.h +++ b/src/Ip6Packet_t.h @@ -9,4 +9,5 @@ namespace Tins } typedef std::unique_ptr UPtrIPv6Address; + #endif diff --git a/src/IpVersionRouter.cpp b/src/IpVersionRouter.cpp new file mode 100644 index 0000000..51fccb4 --- /dev/null +++ b/src/IpVersionRouter.cpp @@ -0,0 +1,35 @@ +#include "IpVersionRouter.h" +#include +#include +#include +#include "INetworkInterfaceCard.h" +IpVersionRouter::IpVersionRouter() +{ +} + +IpVersionRouter::~IpVersionRouter() +{ +} + +bool IpVersionRouter::handle(IN const Tins::PDU & pdu, IN IPacketHandler * /* callBackHandler*/) +{ + const Tins::IPv6 * ipv6Pdu = pdu.find_pdu(); + if(ipv6Pdu != nullptr) + { + ipv6Card->sendPacket(pdu); + return true; + } + + const Tins::IP * ipv4Pdu = pdu.find_pdu(); + if(ipv4Pdu == nullptr) + { + const Tins::ARP * arpPdu = pdu.find_pdu(); + if(arpPdu == nullptr) + { + return false; + } + } + + ipv4Card->sendPacket(pdu); + return true; +} diff --git a/src/IpVersionRouter.h b/src/IpVersionRouter.h new file mode 100644 index 0000000..0dd668c --- /dev/null +++ b/src/IpVersionRouter.h @@ -0,0 +1,20 @@ +#ifndef IPVERSIONROUTER_H +#define IPVERSIONROUTER_H + +#include "AbstractRouter.h" +#include "INetworkInterfaceCard_t.h" + +class IpVersionRouter: public AbstractRouter +{ +public: + IpVersionRouter(); + virtual ~IpVersionRouter(); + virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override; + +private: + + SPtrINetworkInterfaceCard ipv6Card; + SPtrINetworkInterfaceCard ipv4Card; +}; + +#endif // ABSTRACTROUTER_H