fix calc of arp hash value

This commit is contained in:
stubbfel
2017-06-08 21:38:27 +02:00
parent d202fdc778
commit c0b8a1b5e0
8 changed files with 78 additions and 18 deletions

View File

@@ -57,17 +57,19 @@ bool ArpToNdpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler *
{ {
case Tins::ARP::REQUEST: case Tins::ARP::REQUEST:
ndpPdu = std::make_unique<Tins::ICMPv6>(Tins::ICMPv6::NEIGHBOUR_SOLICIT); ndpPdu = std::make_unique<Tins::ICMPv6>(Tins::ICMPv6::NEIGHBOUR_SOLICIT);
setSolicitedNodeAddress(*ipv6Pdu, *targetIp6Address); setSolicitedNodeAddress(*ipv6Pdu, *targetIp6Address);
ndpPdu->source_link_layer_addr(senderHwAddr); ndpPdu->source_link_layer_addr(senderHwAddr);
ndpPdu->target_addr(*targetIp6Address); ndpPdu->target_addr(*targetIp6Address);
isRequest = true; isRequest = true;
break; ipv6Pdu->hop_limit(255);
break;
case Tins::ARP::REPLY: case Tins::ARP::REPLY:
ndpPdu = std::make_unique<Tins::ICMPv6>(Tins::ICMPv6::NEIGHBOUR_ADVERT); ndpPdu = std::make_unique<Tins::ICMPv6>(Tins::ICMPv6::NEIGHBOUR_ADVERT);
ipv6Pdu->dst_addr(*targetIp6Address); ipv6Pdu->dst_addr(*targetIp6Address);
ndpPdu->target_addr(*senderIp6Address); ndpPdu->target_addr(*senderIp6Address);
ndpPdu->target_link_layer_addr(senderHwAddr); ipv6Pdu->hop_limit(255);
ndpPdu->target_link_layer_addr(senderHwAddr);
break; break;
default: default:
return false; return false;

View File

@@ -47,6 +47,11 @@ bool Icmp4ToIcmp6PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandl
icmpv6Pdu->sequence(icmpv4Pdu->sequence()); icmpv6Pdu->sequence(icmpv4Pdu->sequence());
icmpv6Pdu->code(0); icmpv6Pdu->code(0);
if (icmpv4Pdu->inner_pdu() != nullptr)
{
icmpv6Pdu->inner_pdu(icmpv4Pdu->inner_pdu()->clone());
}
// replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler // replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler
Tins::PDU * clonePdu = pdu.clone(); Tins::PDU * clonePdu = pdu.clone();
Tins::IP * ipPdu = clonePdu->find_pdu<Tins::IP>(); Tins::IP * ipPdu = clonePdu->find_pdu<Tins::IP>();

View File

@@ -28,7 +28,7 @@ bool Icmp6ToIcmp4PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandl
return false; return false;
} }
// create icmp6 pdu // create icmp6 pdu
const Tins::ICMPv6::Types type = icmpv6Pdu->type(); const Tins::ICMPv6::Types type = icmpv6Pdu->type();
std::unique_ptr<Tins::ICMP> icmpv4Pdu; std::unique_ptr<Tins::ICMP> icmpv4Pdu;
switch (type) switch (type)
@@ -53,6 +53,11 @@ bool Icmp6ToIcmp4PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandl
icmpv4Pdu->sequence(icmpv6Pdu->sequence()); icmpv4Pdu->sequence(icmpv6Pdu->sequence());
icmpv4Pdu->code(0); icmpv4Pdu->code(0);
if (icmpv6Pdu->inner_pdu() != nullptr)
{
icmpv4Pdu->inner_pdu(icmpv6Pdu->inner_pdu()->clone());
}
// replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler // replace icmp4 with icmp6 content, adress translation will bo den by Ip4ToIp6PacketHandler
Tins::PDU * clonePdu = pdu.clone(); Tins::PDU * clonePdu = pdu.clone();
Tins::IPv6 * ipv6Pdu = clonePdu->find_pdu<Tins::IPv6>(); Tins::IPv6 * ipv6Pdu = clonePdu->find_pdu<Tins::IPv6>();
@@ -61,6 +66,7 @@ bool Icmp6ToIcmp4PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandl
return false; return false;
} }
ipv6Pdu->inner_pdu(*icmpv4Pdu); ipv6Pdu->inner_pdu(*icmpv4Pdu);
return Ip6ToIp4PacketHandler::handle(*clonePdu, callBackHandler); return Ip6ToIp4PacketHandler::handle(*clonePdu, callBackHandler);
} }

View File

@@ -36,7 +36,9 @@ bool Ip4ToIp6PacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler *
IpAddressTranslator::toIpv6Address(ipv4Pdu->dst_addr(), *dstIp6Address); IpAddressTranslator::toIpv6Address(ipv4Pdu->dst_addr(), *dstIp6Address);
// create ip4 pdu // create ip4 pdu
std::unique_ptr<const Tins::IPv6> ipv6Pdu = std::make_unique<const Tins::IPv6>(*dstIp6Address,*srcIp6Address); std::unique_ptr<Tins::IPv6> ipv6Pdu = std::make_unique<Tins::IPv6>(*dstIp6Address,*srcIp6Address);
ipv6Pdu->hop_limit(64);
ipv6Pdu->flow_label(11);
// create forwarding frame // create forwarding frame
std::unique_ptr<Tins::EthernetII> ptrForwardEthPdu = std::make_unique<Tins::EthernetII>(); std::unique_ptr<Tins::EthernetII> ptrForwardEthPdu = std::make_unique<Tins::EthernetII>();

View File

@@ -1,6 +1,7 @@
#include "TinsNetworkInterfaceCard.h" #include "TinsNetworkInterfaceCard.h"
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <tins/arp.h>
#include <tins/ethernetII.h> #include <tins/ethernetII.h>
#include <tins/network_interface.h> #include <tins/network_interface.h>
#include <tins/packet_sender.h> #include <tins/packet_sender.h>
@@ -48,7 +49,25 @@ TinsNetworkInterfaceCard::~TinsNetworkInterfaceCard()
stopListen(); stopListen();
} }
bool TinsNetworkInterfaceCard::handle(const Tins::PDU &pdu, IPacketHandler *callBackHandler) std::size_t TinsNetworkInterfaceCard::calcHashValue(Tins::PDU & phyLayerLessPdu)
{
const Tins::ARP * arpPdu = phyLayerLessPdu.find_pdu<Tins::ARP>();
ByteVector byteVector;
if(arpPdu != nullptr)
{
Tins::ARP arpNorm(arpPdu->target_ip_addr(), arpPdu->sender_ip_addr());
byteVector = arpNorm.serialize();
}
else
{
byteVector = phyLayerLessPdu.serialize();
}
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
return byteVectorHashValue;
}
bool TinsNetworkInterfaceCard::handle(const Tins::PDU &pdu, IPacketHandler * /*callBackHandler*/)
{ {
if (!isSnifferRunning) if (!isSnifferRunning)
{ {
@@ -63,9 +82,8 @@ bool TinsNetworkInterfaceCard::handle(const Tins::PDU &pdu, IPacketHandler *call
//was the pdu sent by me? //was the pdu sent by me?
Tins::PDU * phyLayerLessPdu = getPhyLessPduPtr(*clonePdu); Tins::PDU * phyLayerLessPdu = getPhyLessPduPtr(*clonePdu);
const ByteVector byteVector = phyLayerLessPdu->serialize(); const std::size_t byteVectorHashValue = calcHashValue(*phyLayerLessPdu);
delete clonePdu; delete clonePdu;
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
if(searchAndRemoveHashListItem(byteVectorHashValue)) if(searchAndRemoveHashListItem(byteVectorHashValue))
{ {
return true; return true;
@@ -93,7 +111,11 @@ void TinsNetworkInterfaceCard::sendPacket(const Tins::PDU &pdu)
if (phyLayerLessPdu != nullptr) if (phyLayerLessPdu != nullptr)
{ {
addPduToHashList(*phyLayerLessPdu); addPduToHashList(*phyLayerLessPdu);
packetSender->send(clonePduRef); printf("len: %u, type: %s \n", clonePduRef.size(), typeid(clonePduRef).name());
if (clonePduRef.size() < 1500)
{
packetSender->send(clonePduRef);
}
} }
delete clonePdu; delete clonePdu;
@@ -106,8 +128,7 @@ void TinsNetworkInterfaceCard::addPduToHashList(IN Tins::PDU &pdu)
return; return;
} }
const ByteVector byteVector = pdu.serialize(); const std::size_t byteVectorHashValue = calcHashValue(pdu);
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
std::lock_guard<std::mutex> lockGuard(*hashListMutex); std::lock_guard<std::mutex> lockGuard(*hashListMutex);
sendPduHashList->push_back(byteVectorHashValue); sendPduHashList->push_back(byteVectorHashValue);
} }

View File

@@ -20,7 +20,7 @@ public:
virtual ~TinsNetworkInterfaceCard(); virtual ~TinsNetworkInterfaceCard();
virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override; virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * = nullptr) override;
virtual void sendPacket(IN const Tins::PDU & pdu) override; virtual void sendPacket(IN const Tins::PDU & pdu) override;
virtual void startListen() override; virtual void startListen() override;
virtual void stopListen() override; virtual void stopListen() override;
@@ -44,5 +44,6 @@ private:
std::atomic<bool> isSnifferRunning; std::atomic<bool> isSnifferRunning;
SPtrIPacketHandlerList handlerList; SPtrIPacketHandlerList handlerList;
std::string sniffNetworkInterfaceName; std::string sniffNetworkInterfaceName;
static std::size_t calcHashValue(Tins::PDU & phyLayerLessPdu);
}; };
#endif #endif

View File

@@ -20,6 +20,7 @@ namespace TestIp6ToIp4PacketHandler
{ {
REQUIRE(currentInputPdu != nullptr); REQUIRE(currentInputPdu != nullptr);
REQUIRE(answerPdu.find_pdu<Tins::IPv6>() == nullptr); REQUIRE(answerPdu.find_pdu<Tins::IPv6>() == nullptr);
REQUIRE(answerPdu.find_pdu<Tins::TCP>() != nullptr);
const Tins::IP * ip = answerPdu.find_pdu<Tins::IP>(); const Tins::IP * ip = answerPdu.find_pdu<Tins::IP>();
REQUIRE(ip != nullptr); REQUIRE(ip != nullptr);
@@ -51,7 +52,8 @@ TEST_CASE( "test Ip6ToIp4PacketHandler", "[Ip6ToIp4PacketHandler]" ) {
return true; return true;
}); });
Tins::EthernetII pkt = Tins::EthernetII() / Tins::IPv6() / Tins::TCP(); Tins::IPv6 tmpPkt = Tins::IPv6() / Tins::TCP();
Tins::EthernetII pkt = Tins::EthernetII() / tmpPkt;
TestIp6ToIp4PacketHandler::currentInputPdu = &pkt; TestIp6ToIp4PacketHandler::currentInputPdu = &pkt;
REQUIRE(handler.handle(pkt, nullptr) == false); REQUIRE(handler.handle(pkt, nullptr) == false);
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true); REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);

View File

@@ -1,7 +1,8 @@
#include "fakeit.hpp" #include "fakeit.hpp"
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include "tins/ethernetII.h" #include <tins/arp.h>
#include <tins/ethernetII.h>
#include <tins/ip.h> #include <tins/ip.h>
#include <tins/ipv6.h> #include <tins/ipv6.h>
#include <tins/ip_address.h> #include <tins/ip_address.h>
@@ -27,6 +28,15 @@ namespace TestTinsNetworkInterfaceCard
if(ip1 != nullptr && (ip1->dst_addr() == ip2->dst_addr())) if(ip1 != nullptr && (ip1->dst_addr() == ip2->dst_addr()))
{ {
foundPduCount++; foundPduCount++;
return true;
}
const Tins::ARP * arp1 = pdu.find_pdu<Tins::ARP>();
const Tins::ARP * arp2 = currentInputPdu->find_pdu<Tins::ARP>();
if(arp1 != nullptr && (arp1->target_ip_addr() == arp2->target_ip_addr()))
{
foundPduCount++;
return true;
} }
return true; return true;
@@ -43,7 +53,7 @@ TEST_CASE( "test send and receive Packet", "[TinsNetworkInterfaceCard_SendRec]"
Mock<IPacketHandler> mockHandler(*sptrMockHandler); Mock<IPacketHandler> mockHandler(*sptrMockHandler);
TestTinsNetworkInterfaceCard::foundPduCount = 0; TestTinsNetworkInterfaceCard::foundPduCount = 0;
ptrPacketSniffer->getHandlerList().push_back(sptrMockHandler); ptrPacketSniffer->getHandlerList().push_back(sptrMockHandler);
Tins::EthernetII pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IP("1.2.3.4", "4.3.2.1") / Tins::TCP(); Tins::EthernetII pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IP("1.2.3.4", "4.3.2.1") / Tins::TCP();
TestTinsNetworkInterfaceCard::currentInputPdu = &pkt; TestTinsNetworkInterfaceCard::currentInputPdu = &pkt;
std::thread sniffThread(&TinsNetworkInterfaceCard::startListen, ptrPacketSniffer.get()); std::thread sniffThread(&TinsNetworkInterfaceCard::startListen, ptrPacketSniffer.get());
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
@@ -80,4 +90,15 @@ TEST_CASE( "test send and receive Packet", "[TinsNetworkInterfaceCard_SendRec]"
ptrPacketSniffer->stopListen(); ptrPacketSniffer->stopListen();
sniffThread3.join(); sniffThread3.join();
REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 4); REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 4);
pkt = Tins::ARP::make_arp_request("1.2.3.4", "4.3.2.1", "11:22:33:44:55:66");
std::thread sniffThread4(&TinsNetworkInterfaceCard::startListen, ptrPacketSniffer.get());
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSniffer->sendPacket(pkt);
ptrPacketSender->sendPacket(pkt);
ptrPacketSniffer->sendPacket(pkt);
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSniffer->stopListen();
sniffThread4.join();
REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 5);
} }