add test fo receive and sending packets
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
90
test/src/TestTinsNetworkCard.cpp
Normal file
90
test/src/TestTinsNetworkCard.cpp
Normal 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();*/
|
||||
}
|
||||
Reference in New Issue
Block a user