add src/TinsNetworkInterfaceCard_t.h (send pdu and store their hash in a thread safe list)
This commit is contained in:
Submodule lib/libtins updated: 25c8802f62...7977ce6fc3
@@ -1,4 +1,5 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifndef MAIN_T_H
|
||||
#define MAIN_T_H
|
||||
|
||||
110
src/TinsNetworkInterfaceCard.cpp
Normal file
110
src/TinsNetworkInterfaceCard.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "TinsNetworkInterfaceCard.h"
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <tins/packet_sender.h>
|
||||
#include <tins/network_interface.h>
|
||||
#include <tins/sniffer.h>
|
||||
|
||||
ByteVectorHash TinsNetworkInterfaceCard::byteVectorHash;
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard() : TinsNetworkInterfaceCard(Tins::NetworkInterface::default_interface())
|
||||
{
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const std::string& name) : TinsNetworkInterfaceCard(name.c_str())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const char* name) : TinsNetworkInterfaceCard(Tins::NetworkInterface(name))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::IPv4Address & ip) : TinsNetworkInterfaceCard(Tins::NetworkInterface(ip))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::IPv6Address & ipv6) : TinsNetworkInterfaceCard(Tins::NetworkInterface(ipv6))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface)
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::~TinsNetworkInterfaceCard()
|
||||
{
|
||||
}
|
||||
|
||||
bool TinsNetworkInterfaceCard::handle(const Tins::PDU &pdu, IPacketHandler *callBackHandler)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TinsNetworkInterfaceCard::sendPacket(const Tins::PDU &pdu)
|
||||
{
|
||||
Tins::PDU * clonePdu = pdu.clone();
|
||||
if (clonePdu == nullptr){
|
||||
return;
|
||||
}
|
||||
|
||||
Tins::PDU & clonePduRef = *clonePdu;
|
||||
Tins::PDU * phyLayerLessPdu = getPhyLessPduPtr(clonePduRef);
|
||||
|
||||
// layer3 only
|
||||
if (phyLayerLessPdu != nullptr)
|
||||
{
|
||||
|
||||
packetSender->send(clonePduRef);
|
||||
}
|
||||
|
||||
delete clonePdu;
|
||||
}
|
||||
|
||||
void TinsNetworkInterfaceCard::addPduToHashList(IN Tins::PDU &pdu)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
|
||||
const ByteVector byteVector = pdu.serialize();
|
||||
const std::size_t byteVectorHashValue = byteVectorHash(byteVector);
|
||||
sendPduHashList->push_back(byteVectorHashValue);
|
||||
}
|
||||
|
||||
bool TinsNetworkInterfaceCard::searchAndRemoveHashListItem(IN const std::size_t removedHash)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
|
||||
const HashList::const_iterator start = sendPduHashList->cbegin();
|
||||
const HashList::const_iterator end = sendPduHashList->cend();
|
||||
const HashList::const_iterator findIt = std::find(start, end, removedHash);
|
||||
if (findIt == end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sendPduHashList->erase(findIt);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TinsNetworkInterfaceCard::startListen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TinsNetworkInterfaceCard::stopListen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU * TinsNetworkInterfaceCard::getPhyLessPduPtr(IN const Tins::PDU & pdu) const
|
||||
{
|
||||
return pdu.inner_pdu();
|
||||
}
|
||||
40
src/TinsNetworkInterfaceCard.h
Normal file
40
src/TinsNetworkInterfaceCard.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef TINSNETWORKINTERFACECARD_H
|
||||
#define TINSNETWORKINTERFACECARD_H
|
||||
|
||||
#include "TinsNetworkInterfaceCard_t.h"
|
||||
#include "INetworkInterfaceCard_t.h"
|
||||
#include "INetworkInterfaceCard.h"
|
||||
#include "Ip4Packet_t.h"
|
||||
#include "Ip6Packet_t.h"
|
||||
|
||||
class TinsNetworkInterfaceCard : public INetworkInterfaceCard
|
||||
{
|
||||
public:
|
||||
TinsNetworkInterfaceCard();
|
||||
TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface);
|
||||
TinsNetworkInterfaceCard(const std::string& name);
|
||||
TinsNetworkInterfaceCard(const char* name);
|
||||
TinsNetworkInterfaceCard(const Tins::IPv4Address & ip);
|
||||
TinsNetworkInterfaceCard(const Tins::IPv6Address & ipv6);
|
||||
|
||||
virtual ~TinsNetworkInterfaceCard();
|
||||
|
||||
virtual bool handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler = nullptr) override;
|
||||
virtual void sendPacket(IN const Tins::PDU & pdu) override;
|
||||
virtual void startListen() override;
|
||||
virtual void stopListen() override;
|
||||
|
||||
private:
|
||||
|
||||
Tins::PDU * getPhyLessPduPtr(IN const 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;
|
||||
};
|
||||
#endif
|
||||
58
src/TinsNetworkInterfaceCard_t.h
Normal file
58
src/TinsNetworkInterfaceCard_t.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef TINSNETWORKINTERFACECARD_T_H
|
||||
#define TINSNETWORKINTERFACECARD_T_H
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "Main_t.h"
|
||||
|
||||
typedef std::vector<uint8_t> ByteVector;
|
||||
|
||||
namespace Tins
|
||||
{
|
||||
class NetworkInterface;
|
||||
class PacketSender;
|
||||
class Sniffer;
|
||||
class SnifferConfiguration;
|
||||
}
|
||||
|
||||
typedef std::unique_ptr<Tins::Sniffer> UPtrSniffer;
|
||||
typedef std::unique_ptr<Tins::SnifferConfiguration> UPtrSnifferConfiguration;
|
||||
typedef std::unique_ptr<Tins::PacketSender> UPtrPacketSender;
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t& seed, const T& v)
|
||||
{
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
template<>
|
||||
struct hash<ByteVector>
|
||||
{
|
||||
std::size_t operator()(ByteVector const& byte_vector) const
|
||||
{
|
||||
std::size_t resultHash = 0;
|
||||
for (uint8_t byte : byte_vector)
|
||||
{
|
||||
hash_combine(resultHash, byte);
|
||||
}
|
||||
|
||||
return resultHash;
|
||||
}
|
||||
};
|
||||
|
||||
class mutex;
|
||||
}
|
||||
|
||||
typedef std::hash<ByteVector> ByteVectorHash;
|
||||
|
||||
typedef std::shared_ptr<std::mutex> SPtrMutex;
|
||||
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;
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "fakeit.hpp"
|
||||
#include "tins/ethernetII.h"
|
||||
#include <fakeit.hpp>
|
||||
#include <tins/ethernetII.h>
|
||||
#include <tins/ip.h>
|
||||
#include <tins/ipv6.h>
|
||||
#include <tins/ip_address.h>
|
||||
@@ -7,8 +7,11 @@
|
||||
#include <tins/tcp.h>
|
||||
#include "Ip6ToIp4PacketHandler.h"
|
||||
#include "IpAddressTranslator.h"
|
||||
#include "TinsNetworkInterfaceCard_t.h"
|
||||
using namespace fakeit;
|
||||
|
||||
|
||||
|
||||
namespace TestIp6ToIp4PacketHandler
|
||||
{
|
||||
Tins::PDU * currentInputPdu = nullptr;
|
||||
@@ -57,4 +60,22 @@ TEST_CASE( "test Ip6ToIp4PacketHandler", "[Ip6ToIp4PacketHandler]" ) {
|
||||
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::1", "::2") / Tins::TCP();
|
||||
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
|
||||
Verify(Method(mockHandler, handle)).Twice();
|
||||
|
||||
// test pkt hashes
|
||||
Tins::EthernetII * clonePkt = pkt.clone();
|
||||
REQUIRE((long) clonePkt != (long) &pkt);
|
||||
Tins::PDU::serialization_type ser_pkt = pkt.serialize();
|
||||
Tins::PDU::serialization_type ser_clonepkt = clonePkt->serialize();
|
||||
REQUIRE(ser_pkt == ser_clonepkt);
|
||||
|
||||
Tins::PDU & pdu = *((Tins::PDU *)&pkt);
|
||||
std::hash<Tins::PDU::serialization_type>pdu_hash;
|
||||
std::size_t h1 = pdu_hash(ser_pkt);
|
||||
std::size_t h2 = pdu_hash(ser_clonepkt);
|
||||
|
||||
REQUIRE(h1 == h2);
|
||||
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::2", "::1") / Tins::TCP();
|
||||
ser_pkt = pkt.serialize();
|
||||
h1 = pdu_hash(ser_pkt);
|
||||
REQUIRE(h1 != h2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user