add test fo receive and sending packets

This commit is contained in:
stubbfel
2017-03-16 23:36:14 +01:00
parent 76e86f556a
commit 0facb2f57b
4 changed files with 179 additions and 9 deletions

View File

@@ -32,40 +32,67 @@ TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::IPv6Address & ipv
}
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface)
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface) : sniffNetworkInterfaceName(networkInterface.name())
{
snifferConfig = std::make_unique<Tins::SnifferConfiguration>();
snifferConfig->set_promisc_mode(true);
snifferConfig->set_immediate_mode(true);
sniffer = std::make_unique<Tins::Sniffer>(networkInterface.name());
packetSender = std::make_unique<Tins::PacketSender>(networkInterface);
sendPduHashList = std::make_unique<HashList>();
hashListMutex = std::make_unique<std::mutex>();
isSnifferRunning = false;
}
TinsNetworkInterfaceCard::~TinsNetworkInterfaceCard()
{
stopListen();
}
bool TinsNetworkInterfaceCard::handle(const Tins::PDU &pdu, IPacketHandler *callBackHandler)
{
return false;
if (!isSnifferRunning)
{
return false;
}
Tins::PDU * clonePdu = pdu.clone();
if (clonePdu == nullptr)
{
return true;
}
//was the pdu sent by me?
Tins::PDU * phyLayerLessPdu = getPhyLessPduPtr(*clonePdu);
const ByteVector byteVector = phyLayerLessPdu->serialize();
delete clonePdu;
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
if(searchAndRemoveHashListItem(byteVectorHashValue))
{
return true;
}
for (SPtrIPacketHandler handler: handlerList)
{
handler->handle(pdu, nullptr);
}
return true;
}
void TinsNetworkInterfaceCard::sendPacket(const Tins::PDU &pdu)
{
Tins::PDU * clonePdu = pdu.clone();
if (clonePdu == nullptr){
if (clonePdu == nullptr)
{
return;
}
Tins::PDU & clonePduRef = *clonePdu;
Tins::PDU * phyLayerLessPdu = getPhyLessPduPtr(clonePduRef);
// layer3 only
if (phyLayerLessPdu != nullptr)
{
addPduToHashList(*phyLayerLessPdu);
packetSender->send(clonePduRef);
}
@@ -74,9 +101,14 @@ void TinsNetworkInterfaceCard::sendPacket(const Tins::PDU &pdu)
void TinsNetworkInterfaceCard::addPduToHashList(IN Tins::PDU &pdu)
{
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
if (!isSnifferRunning)
{
return;
}
const ByteVector byteVector = pdu.serialize();
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
sendPduHashList->push_back(byteVectorHashValue);
}
@@ -97,12 +129,28 @@ bool TinsNetworkInterfaceCard::searchAndRemoveHashListItem(IN const std::size_t
void TinsNetworkInterfaceCard::startListen()
{
if (isSnifferRunning)
{
return;
}
UPtrSniffer sniffer = std::make_unique<Tins::Sniffer>(sniffNetworkInterfaceName, *snifferConfig);
isSnifferRunning = true;
sniffer->sniff_loop(make_sniffer_handler(this, &TinsNetworkInterfaceCard::tinsSnifferCallback));
}
void TinsNetworkInterfaceCard::stopListen()
{
if (!isSnifferRunning)
{
return;
}
isSnifferRunning = false;
Tins::EthernetII pkt = Tins::EthernetII();
packetSender->send(pkt);
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
sendPduHashList->clear();
}
Tins::PDU * TinsNetworkInterfaceCard::getPhyLessPduPtr(IN Tins::PDU & pdu) const
@@ -115,3 +163,23 @@ Tins::PDU * TinsNetworkInterfaceCard::getPhyLessPduPtr(IN Tins::PDU & pdu) const
return getPhyLessPduPtr(*(ethPdu->inner_pdu()));
}
Tins::SnifferConfiguration & TinsNetworkInterfaceCard::getSnifferConfig() const
{
return *snifferConfig;
}
bool TinsNetworkInterfaceCard::tinsSnifferCallback(Tins::PDU &some_pdu)
{
return handle(some_pdu, nullptr);
}
SPtrIPacketHandlerList & TinsNetworkInterfaceCard::getHandlerList()
{
return handlerList;
}
bool TinsNetworkInterfaceCard::isSniffRunning() const
{
return isSnifferRunning;
}

View File

@@ -1,6 +1,7 @@
#ifndef TINSNETWORKINTERFACECARD_H
#define TINSNETWORKINTERFACECARD_H
#include <atomic>
#include "TinsNetworkInterfaceCard_t.h"
#include "INetworkInterfaceCard_t.h"
#include "INetworkInterfaceCard.h"
@@ -24,17 +25,24 @@ public:
virtual void startListen() override;
virtual void stopListen() override;
Tins::SnifferConfiguration & getSnifferConfig() const;
SPtrIPacketHandlerList & getHandlerList();
bool isSniffRunning() const;
private:
Tins::PDU * getPhyLessPduPtr(IN Tins::PDU & pdu) const;
bool tinsSnifferCallback(IN Tins::PDU & some_pdu);
Tins::PDU * getPhyLessPduPtr(IN Tins::PDU & pdu) const;
void addPduToHashList(IN Tins::PDU &pdu);
bool searchAndRemoveHashListItem(IN const std::size_t removedHash);
UPtrSniffer sniffer;
UPtrSnifferConfiguration snifferConfig;
UPtrPacketSender packetSender;
static ByteVectorHash byteVectorHash;
UPtrHashList sendPduHashList;
UPtrMutex hashListMutex;
std::atomic<bool> isSnifferRunning;
SPtrIPacketHandlerList handlerList;
std::string sniffNetworkInterfaceName;
};
#endif

View File

@@ -55,4 +55,8 @@ typedef std::unique_ptr<std::mutex> UPtrMutex;
typedef std::vector<size_t> HashList;
typedef std::shared_ptr<HashList> SPtrrHashList;
typedef std::unique_ptr<HashList> UPtrHashList;
class TinsNetworkInterfaceCard;
typedef std::shared_ptr<TinsNetworkInterfaceCard> SPtrTinsNetworkInterfaceCard;
#endif

View File

@@ -0,0 +1,90 @@
#include "fakeit.hpp"
#include <chrono>
#include <thread>
#include "tins/ethernetII.h"
#include <tins/ip.h>
#include <tins/ipv6.h>
#include <tins/ip_address.h>
#include <tins/ipv6_address.h>
#include <tins/tcp.h>
#include <tins/sniffer.h>
#include "TinsNetworkInterfaceCard.h"
using namespace fakeit;
namespace TestTinsNetworkInterfaceCard
{
Tins::PDU * currentInputPdu = nullptr;
int foundPduCount;
struct MockPacketHandler : IPacketHandler
{
virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override
{
const Tins::IP * ip1 = pdu.find_pdu<Tins::IP>();
const Tins::IP * ip2 = currentInputPdu->find_pdu<Tins::IP>();
if(ip1 != nullptr && (ip1->dst_addr() == ip2->dst_addr()))
{
foundPduCount++;
}
return true;
}
};
}
TEST_CASE( "test send and receive Packet", "[TinsNetworkInterfaceCard_SendRec]" )
{
SPtrTinsNetworkInterfaceCard ptrPacketSender = std::make_shared<TinsNetworkInterfaceCard>();
SPtrTinsNetworkInterfaceCard ptrPacketSniffer = std::make_shared<TinsNetworkInterfaceCard>();
SPtrIPacketHandler sptrMockHandler = std::make_shared<TestTinsNetworkInterfaceCard::MockPacketHandler>();
Mock<IPacketHandler> mockHandler(*sptrMockHandler);
TestTinsNetworkInterfaceCard::foundPduCount = 0;
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();
TestTinsNetworkInterfaceCard::currentInputPdu = &pkt;
std::thread sniffThread(&TinsNetworkInterfaceCard::startListen, ptrPacketSniffer.get());
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSender->sendPacket(pkt);
ptrPacketSender->sendPacket(pkt);
ptrPacketSender->sendPacket(pkt);
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSniffer->stopListen();
ptrPacketSender->sendPacket(pkt);
ptrPacketSender->sendPacket(pkt);
ptrPacketSender->sendPacket(pkt);
sniffThread.join();
REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 3);
std::thread sniffThread2(&TinsNetworkInterfaceCard::startListen, ptrPacketSniffer.get());
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSniffer->sendPacket(pkt);
ptrPacketSniffer->sendPacket(pkt);
ptrPacketSniffer->sendPacket(pkt);
std::this_thread::sleep_for(std::chrono::seconds(2));
ptrPacketSniffer->stopListen();
ptrPacketSniffer->sendPacket(pkt);
ptrPacketSniffer->sendPacket(pkt);
ptrPacketSniffer->sendPacket(pkt);
sniffThread2.join();
REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 3);
std::thread sniffThread3(&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();
sniffThread3.join();
REQUIRE(TestTinsNetworkInterfaceCard::foundPduCount == 4);
/*REQUIRE(handler.handle(pkt, nullptr) == false);
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Once();
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();
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Twice();*/
}