64 lines
1.8 KiB
C++
64 lines
1.8 KiB
C++
#include "Ip6ToIp4PacketHandler.h"
|
|
#include "tins/ethernetII.h"
|
|
#include <tins/ip.h>
|
|
#include <tins/ipv6.h>
|
|
#include "IpAddressTranslator.h"
|
|
|
|
namespace std
|
|
{
|
|
template<typename T, typename ... Args>
|
|
std::unique_ptr<T> make_unique(Args && ... args)
|
|
{
|
|
return std::unique_ptr<T>(new T(std::forward<Args>(args) ...));
|
|
}
|
|
}
|
|
|
|
Ip6ToIp4PacketHandler::Ip6ToIp4PacketHandler()
|
|
{}
|
|
Ip6ToIp4PacketHandler::~Ip6ToIp4PacketHandler()
|
|
{}
|
|
bool Ip6ToIp4PacketHandler::handle(const Tins::PDU &pdu, IN IPacketHandler * callBackHandler)
|
|
{
|
|
if (callBackHandler == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const Tins::IPv6 * ipv6Pdu = pdu.find_pdu<Tins::IPv6>();
|
|
if(ipv6Pdu == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const Tins::EthernetII * ethPdu = pdu.find_pdu<Tins::EthernetII>();
|
|
if(ethPdu == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const Tins::PDU * ipPayloadPdu = ipv6Pdu->inner_pdu();
|
|
if(ipPayloadPdu == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// convert ipv6 addresses to ipv4 addresses
|
|
const uint32_t srcIp4AddressBytes = IpAddressTranslator::toIpv4AddressBytes(ipv6Pdu->src_addr());
|
|
const uint32_t dstIp4AddressBytes = IpAddressTranslator::toIpv4AddressBytes(ipv6Pdu->dst_addr());
|
|
std::unique_ptr<const Tins::IPv4Address> srcIp4Address = std::make_unique<const Tins::IPv4Address>(srcIp4AddressBytes);
|
|
std::unique_ptr<const Tins::IPv4Address> dstIp4Address = std::make_unique<const Tins::IPv4Address>(dstIp4AddressBytes);
|
|
|
|
// create ip4 pdu
|
|
std::unique_ptr<const Tins::IP> ipv4Pdu = std::make_unique<const Tins::IP>(*srcIp4Address, *dstIp4Address);
|
|
|
|
// create forwarding frame
|
|
std::unique_ptr<Tins::EthernetII> ptrForwardEthPdu = std::make_unique<Tins::EthernetII>();
|
|
Tins::EthernetII & forwardEthPdu = *ptrForwardEthPdu;
|
|
forwardEthPdu /= *ethPdu;
|
|
forwardEthPdu /= *ipv4Pdu;
|
|
forwardEthPdu /= *ipPayloadPdu;
|
|
|
|
// forward frame
|
|
return callBackHandler->handle(forwardEthPdu, this);
|
|
}
|