#include "ArpToNdpPacketHandler.h" #include #include #include #include #include #include #include #include "HwAddressTranslator.h" #include "IpAddressTranslator.h" ArpToNdpPacketHandler::ArpToNdpPacketHandler(const Tins::IPv6Address & newPrefix) { prefix = std::make_unique(newPrefix); } ArpToNdpPacketHandler::~ArpToNdpPacketHandler() { } void ArpToNdpPacketHandler::setSolicitedNodeAddress(INOUT Tins::IPv6 & ipv6, IN const Tins::IPv6Address & targetIp) { UPtrIPv6Address solicitedNodeAddress = std::make_unique(); Tins::IPv6Address & tmpRef = *solicitedNodeAddress; IpAddressTranslator::toSolicitedNodeAddress(targetIp, tmpRef); ipv6.dst_addr(tmpRef); } 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 UPtrIPv6Address senderIp6Address = std::make_unique(*prefix); UPtrIPv6Address targetIp6Address = std::make_unique(*prefix); const Tins::IPv4Address & targetIp =arpPdu->target_ip_addr(); IpAddressTranslator::toIpv6Address(arpPdu->sender_ip_addr(), *senderIp6Address); IpAddressTranslator::toIpv6Address(targetIp, *targetIp6Address); // create ip4 pdu std::unique_ptr ndpPdu; std::shared_ptr ipv6Pdu = std::make_shared(); ipv6Pdu->src_addr(*senderIp6Address); bool isRequest = false; const Tins::ARP::hwaddress_type & senderHwAddr = arpPdu->sender_hw_addr(); switch (arpPdu->opcode()) { case Tins::ARP::REQUEST: ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_SOLICIT); setSolicitedNodeAddress(*ipv6Pdu, *targetIp6Address); ndpPdu->source_link_layer_addr(senderHwAddr); ndpPdu->target_addr(*targetIp6Address); isRequest = true; break; case Tins::ARP::REPLY: ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_ADVERT); ipv6Pdu->dst_addr(*targetIp6Address); ndpPdu->target_addr(*senderIp6Address); ndpPdu->target_link_layer_addr(senderHwAddr); break; default: return false; } std::shared_ptr ptrOutestPdu; const Tins::EthernetII * ethPdu = pdu.find_pdu(); if(ethPdu != nullptr) { // set eth frame std::shared_ptr ptrEthPdu = std::make_shared(); ptrEthPdu->src_addr(ethPdu->src_addr()); Tins::EthernetII::address_type dstMac; if (isRequest) { // set solicited address UPtrHwAddress solicitedNodeHWAddress = std::make_unique(); HwAddressTranslator::toSolicitedNodeAddress(*targetIp6Address, *solicitedNodeHWAddress); ptrEthPdu->dst_addr(*solicitedNodeHWAddress); } else { ptrEthPdu->dst_addr(ethPdu->dst_addr()); } ptrOutestPdu = ptrEthPdu; *ptrOutestPdu /= *ipv6Pdu; } else { ptrOutestPdu = ipv6Pdu; } Tins::PDU & outestPdu = *ptrOutestPdu; outestPdu /= *ndpPdu; return callBackHandler->handle(outestPdu, this); } const Tins::IPv6Address & ArpToNdpPacketHandler::getPrefix() const { return *prefix; } void ArpToNdpPacketHandler::setPrefix(const Tins::IPv6Address & newPrefix) { *prefix = newPrefix; }