diff --git a/lib/libtins b/lib/libtins index 25c8802..7977ce6 160000 --- a/lib/libtins +++ b/lib/libtins @@ -1 +1 @@ -Subproject commit 25c8802f621a75f04130eb7206f90cd15513c596 +Subproject commit 7977ce6fc39918f62a39a2872d14e3fdb5508db6 diff --git a/src/Main_t.h b/src/Main_t.h index 3a4f3a9..7b367d0 100644 --- a/src/Main_t.h +++ b/src/Main_t.h @@ -1,4 +1,5 @@ #include +#include #ifndef MAIN_T_H #define MAIN_T_H diff --git a/src/TinsNetworkInterfaceCard.cpp b/src/TinsNetworkInterfaceCard.cpp new file mode 100644 index 0000000..696d09f --- /dev/null +++ b/src/TinsNetworkInterfaceCard.cpp @@ -0,0 +1,110 @@ +#include "TinsNetworkInterfaceCard.h" +#include +#include +#include +#include +#include + +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(); + snifferConfig->set_promisc_mode(true); + snifferConfig->set_immediate_mode(true); + sniffer = std::make_unique(networkInterface.name()); + packetSender = std::make_unique(networkInterface); + sendPduHashList = std::make_unique(); + hashListMutex = std::make_unique(); +} + +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 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 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(); +} diff --git a/src/TinsNetworkInterfaceCard.h b/src/TinsNetworkInterfaceCard.h new file mode 100644 index 0000000..800aecb --- /dev/null +++ b/src/TinsNetworkInterfaceCard.h @@ -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 diff --git a/src/TinsNetworkInterfaceCard_t.h b/src/TinsNetworkInterfaceCard_t.h new file mode 100644 index 0000000..6e9e7ff --- /dev/null +++ b/src/TinsNetworkInterfaceCard_t.h @@ -0,0 +1,58 @@ +#ifndef TINSNETWORKINTERFACECARD_T_H +#define TINSNETWORKINTERFACECARD_T_H + +#include +#include +#include "Main_t.h" + +typedef std::vector ByteVector; + +namespace Tins +{ + class NetworkInterface; + class PacketSender; + class Sniffer; + class SnifferConfiguration; +} + +typedef std::unique_ptr UPtrSniffer; +typedef std::unique_ptr UPtrSnifferConfiguration; +typedef std::unique_ptr UPtrPacketSender; + + +namespace std +{ + template + inline void hash_combine(std::size_t& seed, const T& v) + { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + + template<> + struct hash + { + 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 ByteVectorHash; + +typedef std::shared_ptr SPtrMutex; +typedef std::unique_ptr UPtrMutex; + +typedef std::vector HashList; +typedef std::shared_ptr SPtrrHashList; +typedef std::unique_ptr UPtrHashList; +#endif diff --git a/test/src/TestIp6ToIp4PacketHandler.cpp b/test/src/TestIp6ToIp4PacketHandler.cpp index 43750c3..c2ecb64 100644 --- a/test/src/TestIp6ToIp4PacketHandler.cpp +++ b/test/src/TestIp6ToIp4PacketHandler.cpp @@ -1,5 +1,5 @@ -#include "fakeit.hpp" -#include "tins/ethernetII.h" +#include +#include #include #include #include @@ -7,8 +7,11 @@ #include #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::hashpdu_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); }