add NdpToArpPacketHandler

This commit is contained in:
stubbfel
2017-02-16 23:33:50 +01:00
parent 86ff923e8a
commit 471bd9459c
5 changed files with 117 additions and 4 deletions

View File

@@ -1,5 +1,4 @@
#include "ArpToNdpPacketHandler.h"
#include <regex>
#include <tins/ethernetII.h>
#include <tins/arp.h>
#include <tins/icmpv6.h>
@@ -28,7 +27,7 @@ void ArpToNdpPacketHandler::setSolicitedNodeAddress(INOUT Tins::IPv6 & ipv6, IN
bool ArpToNdpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler)
{
// callback handvet requeried
// callback handler requeried
if (callBackHandler == nullptr)
{
return false;

View File

@@ -4,7 +4,6 @@
#include "AbstractPacketHandler.h"
#include "IPacketHandler_t.h"
#include "Ip6Packet_t.h"
#include "Ip4Packet_t.h"
class ArpToNdpPacketHandler : public AbstractPacketHandler
{

View File

@@ -0,0 +1,99 @@
#include "NdpToArpPacketHandler.h"
#include <tins/ethernetII.h>
#include <tins/arp.h>
#include <tins/icmpv6.h>
#include <tins/ipv6.h>
#include <tins/ip_address.h>
#include <tins/ipv6_address.h>
#include "IpAddressTranslator.h"
NdpToArpPacketHandler::NdpToArpPacketHandler()
{
}
NdpToArpPacketHandler::~NdpToArpPacketHandler()
{
}
bool NdpToArpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler)
{
// callback handler requeried
if (callBackHandler == nullptr)
{
return false;
}
// get ipv6 packet
const Tins::IPv6 * ipPdu = pdu.find_pdu<Tins::IPv6>();
if(ipPdu == nullptr)
{
return false;
}
// get ipcmp packet, which has the target address field
const Tins::ICMPv6 * ndpPdu = pdu.find_pdu<Tins::ICMPv6>();
if(ndpPdu == nullptr || !ndpPdu->has_target_addr())
{
return false;
}
// translate target address to ipv4
const Tins::IPv6Address & targetIp6Address = ndpPdu->target_addr();
UPtrIPv4Address targetIp = std::make_unique<Tins::IPv4Address>(IpAddressTranslator::toIpv4AddressBytes(targetIp6Address));
// create arp pdu
Tins::ICMPv6::hwaddress_type senderHwAddr;
const Tins::ICMPv6::option * ptrHwAddressOption;
const Tins::ICMPv6::Types ndpType = ndpPdu->type();
if (ndpType == Tins::ICMPv6::Types::NEIGHBOUR_SOLICIT)
{
ptrHwAddressOption = ndpPdu->search_option(Tins::ICMPv6::OptionTypes::SOURCE_ADDRESS);
if (ptrHwAddressOption == nullptr)
{
const Tins::EthernetII * ethNsPdu = pdu.find_pdu<Tins::EthernetII>();
if(ethNsPdu == nullptr)
{
return false;
}
senderHwAddr = ethNsPdu->src_addr();
}
else
{
senderHwAddr = ptrHwAddressOption->to<Tins::ICMPv6::hwaddress_type>();
}
// create arp request
const Tins::IPv6Address & senderIp6Address = ipPdu->src_addr();
UPtrIPv4Address senderIp = std::make_unique<Tins::IPv4Address>(IpAddressTranslator::toIpv4AddressBytes(senderIp6Address));
Tins::EthernetII arpRequest = Tins::ARP::make_arp_request(*targetIp, *senderIp, senderHwAddr);
return callBackHandler->handle(arpRequest, this);
}
if (ndpType == Tins::ICMPv6::Types::NEIGHBOUR_ADVERT)
{
const Tins::EthernetII * ethNaPdu = pdu.find_pdu<Tins::EthernetII>();
if(ethNaPdu == nullptr)
{
return false;
}
ptrHwAddressOption = ndpPdu->search_option(Tins::ICMPv6::OptionTypes::TARGET_ADDRESS);
if (ptrHwAddressOption == nullptr)
{
senderHwAddr = ethNaPdu->src_addr();
}
else
{
senderHwAddr = ptrHwAddressOption->to<Tins::ICMPv6::hwaddress_type>();
}
// create arp reply
const Tins::IPv6Address & dstIp6Address = ipPdu->dst_addr();
UPtrIPv4Address dstIp = std::make_unique<Tins::IPv4Address>(IpAddressTranslator::toIpv4AddressBytes(dstIp6Address));
Tins::EthernetII arpReply = Tins::ARP::make_arp_reply(*dstIp, *targetIp, ethNaPdu->dst_addr(), senderHwAddr);
return callBackHandler->handle(arpReply, this);
}
return false;// callBackHandler->handle(outestPdu, this);
}

View File

@@ -0,0 +1,14 @@
#ifndef NDPTOARPPACKETHANDLER_H
#define NDPTOARPPACKETHANDLER_H
#include "AbstractPacketHandler.h"
#include "IPacketHandler_t.h"
class NdpToArpPacketHandler : public AbstractPacketHandler
{
public:
NdpToArpPacketHandler();
virtual ~NdpToArpPacketHandler();
virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override;
};
#endif

View File

@@ -42,6 +42,7 @@ namespace TestArpToNdpPacketHandler
{
case Tins::ARP::REQUEST:
isRequest = true;
REQUIRE(ndp->type() == Tins::ICMPv6::NEIGHBOUR_SOLICIT);
REQUIRE(ndp->source_link_layer_addr() == arp->sender_hw_addr());
IpAddressTranslator::toIpv6Address(arp->target_ip_addr(), tmp_ipv6);
@@ -52,6 +53,7 @@ namespace TestArpToNdpPacketHandler
break;
case Tins::ARP::REPLY:
REQUIRE(ndp->type() == Tins::ICMPv6::NEIGHBOUR_ADVERT);
REQUIRE(ndp->target_link_layer_addr() == arp->sender_hw_addr());
REQUIRE(ndp->target_addr()== tmp_ipv6);
@@ -105,7 +107,7 @@ TEST_CASE( "test ArpToNdpPacketHandler", "[ArpToNdpPacketHandler]" ) {
Verify(Method(mockHandler, handle)).Once();
HwAddress to_resolve_mac_address("50:60:70:65:43:21");
Tins::EthernetII arp_reply = Tins::ARP::make_arp_reply(to_resolve_address, own_address, to_resolve_mac_address, own_mac_address);
Tins::EthernetII arp_reply = Tins::ARP::make_arp_reply(own_address, to_resolve_address, own_mac_address, to_resolve_mac_address);
TestArpToNdpPacketHandler::currentInputPdu = &arp_reply;
REQUIRE(handler.handle(arp_reply, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Twice();