From dccc639617ed8e28eed215a408a0f9d3cf417821 Mon Sep 17 00:00:00 2001 From: stubbfel Date: Fri, 4 Mar 2016 01:45:57 +0100 Subject: [PATCH] check outgoing packet , depends of source mac --- .dep.inc | 5 --- CMakeLists.txt | 9 +++-- src/CMakeLists.txt | 8 +--- src/{map => }/NatRange.cpp | 0 src/{map => }/NatRange.h | 0 src/PduSender.cpp | 7 ---- src/PduSender.h | 6 +-- src/PduSniffer.cpp | 20 +++++++--- src/PduSniffer.cpp~ | 74 ++++++++++++++++++++++++++++++++++++ src/PduSniffer.h | 7 ++-- src/main.cpp | 47 ++++++++++++++++------- src/map/main.cpp | 45 ---------------------- src/{map => }/natmap.cpp | 78 ++++++++++++++------------------------ src/{map => }/natmap.h | 22 +++++------ 14 files changed, 174 insertions(+), 154 deletions(-) delete mode 100644 .dep.inc rename src/{map => }/NatRange.cpp (100%) rename src/{map => }/NatRange.h (100%) create mode 100644 src/PduSniffer.cpp~ delete mode 100644 src/map/main.cpp rename src/{map => }/natmap.cpp (89%) rename src/{map => }/natmap.h (86%) diff --git a/.dep.inc b/.dep.inc deleted file mode 100644 index 38ba445..0000000 --- a/.dep.inc +++ /dev/null @@ -1,5 +0,0 @@ -# This code depends on make tool being used -DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES} ${TESTOBJECTFILES})) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 4566a51..502ccb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required(VERSION 3.3.2) project (121Nat) -#link_directories("$ENV{STAGING_DIR}/usr/lib") +INCLUDE_DIRECTORIES(lib/src/jsoncpp/include) +INCLUDE_DIRECTORIES(lib/src/libtins/include) +ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(lib/src/jsoncpp) ADD_SUBDIRECTORY(lib/src/libtins) -ADD_SUBDIRECTORY(src) - - +set_property(TARGET 121Nat PROPERTY CXX_STANDARD 11) +set_property(TARGET 121Nat PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52ca27a..76a18d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,11 +1,5 @@ file(GLOB_RECURSE 121Nat_Src_Files "*.h" "*.cpp") -INCLUDE_DIRECTORIES(../lib/src/libtins/include) -INCLUDE_DIRECTORIES(../lib/src/jsoncpp/include) add_executable(121Nat ${121Nat_Src_Files}) target_link_libraries (121Nat pthread tins jsoncpp_lib_static) -set_property(TARGET 121Nat PROPERTY CXX_STANDARD 11) -set_property(TARGET 121Nat PROPERTY CXX_STANDARD_REQUIRED ON) -install(TARGETS 121Nat - RUNTIME DESTINATION bin -) + diff --git a/src/map/NatRange.cpp b/src/NatRange.cpp similarity index 100% rename from src/map/NatRange.cpp rename to src/NatRange.cpp diff --git a/src/map/NatRange.h b/src/NatRange.h similarity index 100% rename from src/map/NatRange.h rename to src/NatRange.h diff --git a/src/PduSender.cpp b/src/PduSender.cpp index 6e082f7..303a1d2 100644 --- a/src/PduSender.cpp +++ b/src/PduSender.cpp @@ -37,14 +37,11 @@ namespace otonat { } std::cout << "send pdu:" << pdu->size() << std::endl; - bool isIp = false; - NatMap::Checksum ipCheckSum; Tins::IPv4Address dstIp = zeroIp; const Tins::IP * ip = pdu->find_pdu(); if (ip != nullptr) { dstIp = ip->dst_addr(); - ipCheckSum = ip->checksum(); isIp = true; } @@ -58,10 +55,6 @@ namespace otonat { for (NatRange & range : this->map->ranges) { if (range.calcIpRange(true).contains(dstIp)) { std::cout << "send pdu:" << pdu->size() << std::endl; - if (isIp) { - map->pushCheckSumToList(ipCheckSum); - } - sender.send(*pdu, range.interface); delete pdu; break; diff --git a/src/PduSender.h b/src/PduSender.h index 9220e71..cb4fe74 100644 --- a/src/PduSender.h +++ b/src/PduSender.h @@ -1,4 +1,4 @@ -/* +/* * File: PduSender.h * Author: dev * @@ -8,7 +8,7 @@ #ifndef PDUSENDER_H #define PDUSENDER_H -#include "map/natmap.h" +#include "natmap.h" #include #include #include @@ -23,7 +23,7 @@ namespace otonat { virtual ~PduSender(); NatMap * map; void SendPdusFromQueue(); - + std::thread * SendPdusFromQueueThread(); private: Tins::PacketSender sender; diff --git a/src/PduSniffer.cpp b/src/PduSniffer.cpp index 6257d3c..cc9e9ba 100644 --- a/src/PduSniffer.cpp +++ b/src/PduSniffer.cpp @@ -1,7 +1,7 @@ -/* +/* * File: PduSniffer.cpp * Author: dev - * + * * Created on 29. September 2015, 21:29 */ @@ -26,7 +26,7 @@ namespace otonat { for (Tins::Sniffer * sniffer : snifferList) { delete sniffer; } - + this->snifferList.clear(); } @@ -41,6 +41,12 @@ namespace otonat { } bool PduSniffer::sniffPdu(const Tins::PDU& pdu) { + if (map->isOutgoingPdu(pdu, interfaceId)){ + std::cout <<"outgoing:" << interfaceId<isRunnig; + } + + std::cout <<"incomming:" << interfaceId<map->pushPduToIncommingPduQueue(pdu.clone()); return this->isRunnig; @@ -53,16 +59,18 @@ namespace otonat { void PduSniffer::Stop() { this->isRunnig = false; } - + void PduSniffer::SniffInterface(const Tins::NetworkInterface & interface) { + interfaceId = interface.id(); + std::cout <<"create:" << interfaceId<sniff_loop(std::bind(&PduSniffer::sniffPdu, this, std::placeholders::_1)); this->snifferList.push_back(sniffer); } - + std::thread * PduSniffer::SniffInterfaceInNewThread(const Tins::NetworkInterface& interface){ std::thread * newThread = new std::thread(std::bind(&PduSniffer::SniffInterface, this, interface)); return newThread; } -} \ No newline at end of file +} diff --git a/src/PduSniffer.cpp~ b/src/PduSniffer.cpp~ new file mode 100644 index 0000000..76d5a44 --- /dev/null +++ b/src/PduSniffer.cpp~ @@ -0,0 +1,74 @@ +/* + * File: PduSniffer.cpp + * Author: dev + * + * Created on 29. September 2015, 21:29 + */ + +#include "PduSniffer.h" +#include +namespace otonat { + + PduSniffer::PduSniffer(NatMap * map) { + this->map = map; + this->isRunnig = false; + config.set_promisc_mode(true); + config.set_immediate_mode(true); + } + + PduSniffer::PduSniffer(const PduSniffer& orig) : snifferList(orig.snifferList), config(orig.config) { + this->map = orig.map; + this->isRunnig = orig.isRunnig; + } + + PduSniffer::~PduSniffer() { + Stop(); + for (Tins::Sniffer * sniffer : snifferList) { + delete sniffer; + } + + this->snifferList.clear(); + } + + PduSniffer& PduSniffer::operator=(const PduSniffer& rhs) { + if (this == &rhs) return *this; // handle self assignment + + this->map = rhs.map; + this->isRunnig = rhs.isRunnig; + this->config = rhs.config; + this->snifferList = rhs.snifferList; + return *this; + } + + bool PduSniffer::sniffPdu(const Tins::PDU& pdu) { + Tins::EthernetII * ethFrame = pdu.find_pdu(); + if (ethFrame == nullptr){ + return this->isRunnig; + } + + ethFrame->src_addr(); + std::cout <<"sniff pdu:" << pdu.size() <map->pushPduToIncommingPduQueue(pdu.clone()); + return this->isRunnig; + } + + void PduSniffer::Start() { + this->isRunnig = true; + } + + void PduSniffer::Stop() { + this->isRunnig = false; + } + + void PduSniffer::SniffInterface(const Tins::NetworkInterface & interface) { + Start(); + Tins::Sniffer * sniffer = new Tins::Sniffer(interface.name(), config); + sniffer->sniff_loop(std::bind(&PduSniffer::sniffPdu, this, std::placeholders::_1)); + this->snifferList.push_back(sniffer); + } + + std::thread * PduSniffer::SniffInterfaceInNewThread(const Tins::NetworkInterface& interface){ + std::thread * newThread = new std::thread(std::bind(&PduSniffer::SniffInterface, this, interface)); + return newThread; + } +} diff --git a/src/PduSniffer.h b/src/PduSniffer.h index 942c81c..cf36632 100644 --- a/src/PduSniffer.h +++ b/src/PduSniffer.h @@ -1,4 +1,4 @@ -/* +/* * File: PduSniffer.h * Author: dev * @@ -8,7 +8,7 @@ #ifndef PDUSNIFFER_H #define PDUSNIFFER_H -#include "map/natmap.h" +#include "natmap.h" #include #include @@ -17,7 +17,7 @@ namespace otonat { class PduSniffer { public: typedef std::vector SnifferList; - + PduSniffer(NatMap * map); PduSniffer(const PduSniffer& orig); PduSniffer& operator=(const PduSniffer& rhs); @@ -32,6 +32,7 @@ namespace otonat { Tins::SnifferConfiguration config; bool isRunnig; bool sniffPdu(const Tins::PDU &pdu); + NatMap::NetworkInterfaceId interfaceId; }; } diff --git a/src/main.cpp b/src/main.cpp index df627a5..731aa4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,19 +1,29 @@ #include #include #include -#include "map/natmap.h" +#include "natmap.h" #include "PduSniffer.h" #include "PduSender.h" #include #include #include + +template +void delete_them(Container& c) +{ + while(!c.empty()) { + delete c.back(), c.pop_back(); + } + c.clear(); +} + int main(int argc, char** argv) { if (argc < 2){ return 0; } - - otonat::NatMap::NatRangeList list; + + otonat::NatMap::NatRangeList interfaceList; std::ifstream config_doc(argv[1], std::ifstream::binary); Json::Value root; config_doc >> root; @@ -26,20 +36,29 @@ int main(int argc, char** argv) const Tins::NetworkInterface net(name); const otonat::NatRange netRange(net, Tins::IPv4Address(ipStr), Tins::IPv4Address(maskStr)); - list.push_back(netRange); + interfaceList.push_back(netRange); } - - otonat::NatMap natMap = otonat::NatMap(list); - otonat::PduSniffer sniffer(&natMap); + + otonat::NatMap natMap = otonat::NatMap(interfaceList); otonat::PduSender sender(&natMap); - std::thread * mapThread = natMap.translateThread(); - std::thread * senderThread = sender.SendPdusFromQueueThread(); - for (otonat::NatRange & net : list) { - sniffer.SniffInterfaceInNewThread(net.interface); + std::vector snifferList; + std::vector threadList; + threadList.push_back(natMap.translateThread()); + threadList.push_back(sender.SendPdusFromQueueThread()); + for (otonat::NatRange & net : interfaceList) { + otonat::PduSniffer * sniffer = new otonat::PduSniffer(&natMap); + snifferList.push_back(sniffer); + threadList.push_back(sniffer->SniffInterfaceInNewThread(net.interface)); } - - mapThread->join(); - senderThread->join(); + + for (std::thread * thread: threadList) { + thread->join(); + } + + delete_them(threadList); + delete_them(snifferList); + threadList.clear(); + snifferList.clear(); return 0; } diff --git a/src/map/main.cpp b/src/map/main.cpp deleted file mode 100644 index df627a5..0000000 --- a/src/map/main.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include "map/natmap.h" -#include "PduSniffer.h" -#include "PduSender.h" -#include -#include -#include -int main(int argc, char** argv) -{ - if (argc < 2){ - return 0; - } - - otonat::NatMap::NatRangeList list; - std::ifstream config_doc(argv[1], std::ifstream::binary); - Json::Value root; - config_doc >> root; - const Json::Value netcards = root; - for (Json::Value netcard : netcards) { - const std::string name = netcard.getMemberNames()[0].c_str(); - const Json::Value cardMember = netcard[name]; - const std::string ipStr = cardMember["rangeIpAddr"].asString(); - const std::string maskStr = cardMember["rangeNetmask"].asString(); - - const Tins::NetworkInterface net(name); - const otonat::NatRange netRange(net, Tins::IPv4Address(ipStr), Tins::IPv4Address(maskStr)); - list.push_back(netRange); - } - - otonat::NatMap natMap = otonat::NatMap(list); - otonat::PduSniffer sniffer(&natMap); - otonat::PduSender sender(&natMap); - std::thread * mapThread = natMap.translateThread(); - std::thread * senderThread = sender.SendPdusFromQueueThread(); - for (otonat::NatRange & net : list) { - sniffer.SniffInterfaceInNewThread(net.interface); - } - - mapThread->join(); - senderThread->join(); - return 0; -} - diff --git a/src/map/natmap.cpp b/src/natmap.cpp similarity index 89% rename from src/map/natmap.cpp rename to src/natmap.cpp index 8181aff..cc1250f 100644 --- a/src/map/natmap.cpp +++ b/src/natmap.cpp @@ -9,10 +9,6 @@ namespace otonat { ranges.clear(); transMap.clear(); reqIpMap.clear(); - - this->checksumListMutex.lock(); - this->checksumList.clear(); - this->checksumListMutex.unlock(); this->incommingQueueMutex.lock(); while (!incommingPduQueue.empty()) { incommingPduQueue.pop(); @@ -26,9 +22,13 @@ namespace otonat { } this->outgoingQueueMutex.unlock(); + + srcMacAdressNicIdMapMutex.lock(); + srcMacAdressNicIdMap.clear(); + srcMacAdressNicIdMapMutex.unlock(); } - NatMap::NatMap(const NatMap& other) : ranges(other.ranges), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue), checksumList(other.checksumList) { + NatMap::NatMap(const NatMap& other) : ranges(other.ranges), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue),srcMacAdressNicIdMap(other.srcMacAdressNicIdMap) { } NatMap& NatMap::operator=(const NatMap& rhs) { @@ -42,9 +42,9 @@ namespace otonat { this->outgoingQueueMutex.lock(); outgoingPduQueue = rhs.outgoingPduQueue; this->outgoingQueueMutex.unlock(); - this->checksumListMutex.lock(); - this->checksumList = rhs.checksumList; - this->checksumListMutex.unlock(); + this->srcMacAdressNicIdMapMutex.lock(); + this->srcMacAdressNicIdMap = rhs.srcMacAdressNicIdMap; + this->srcMacAdressNicIdMapMutex.unlock(); return *this; } @@ -72,13 +72,6 @@ namespace otonat { } bool NatMap::handleIp(Tins::IP * ip, const Tins::PDU * originPDU) { - Checksum checksum = ip->checksum(); - - if (containChecksumList(checksum)) { - this->popCheckSumToList(checksum); - return false; - } - if (isForMeOrFromMeIp(ip)) { return false; } @@ -241,11 +234,6 @@ namespace otonat { bool NatMap::handleArpReq(Tins::ARP* arp) { const Tins::IPv4Address targetIp = arp->target_ip_addr(); - IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(targetIp); - if (transSenderIpReqIter != reqIpMap.end()) { - return false; - } - IpAdressMap::const_iterator transTargetIpIter = this->transMap.find(targetIp); if (transTargetIpIter == transMap.end()) { SendTranslatedArpRequest(arp); @@ -267,11 +255,6 @@ namespace otonat { bool NatMap::handleArpReply(Tins::ARP* arp) { const Tins::IPv4Address targetIp = arp->target_ip_addr(); - IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(targetIp); - if (transSenderIpReqIter == reqIpMap.end()) { - return false; - } - const Tins::IPv4Address transTargetIp = TranslateArpIp(targetIp); if (transTargetIp == zeroIp) { return false; @@ -285,7 +268,6 @@ namespace otonat { arp->target_ip_addr(transTargetIp); arp->sender_ip_addr(transSenderIp); - return true; } @@ -424,31 +406,29 @@ namespace otonat { } } - void NatMap::pushCheckSumToList(Checksum checksum) { - checksumListMutex.lock(); - if (!containChecksumList(checksum)) { - - this->checksumList.push_back(checksum); - } - - checksumListMutex.unlock(); - } - - void NatMap::popCheckSumToList(Checksum checksum) { - checksumListMutex.lock(); - this->checksumList.remove(checksum); - checksumListMutex.unlock(); - } - - bool NatMap::containChecksumList(Checksum checksum) { - ChecksumList::const_iterator endIter = this->checksumList.end(); - ChecksumList::const_iterator beginIter = this->checksumList.begin(); - ChecksumList::const_iterator findIter = std::find(beginIter, endIter, checksum); - return endIter != findIter; - } - std::thread * NatMap::translateThread() { std::thread * newThread = new std::thread(std::bind(&NatMap::translate, this)); return newThread; } + + bool NatMap::isOutgoingPdu(const Tins::PDU& pdu, NetworkInterfaceId interfaceId){ + const Tins::EthernetII * ethFrame = pdu.find_pdu(); + if (ethFrame == nullptr){ + return false; + } + + MacAddress srcMac = ethFrame->src_addr(); + bool result = false; + srcMacAdressNicIdMapMutex.lock(); + SrcMacAdressNicIdMap::const_iterator endIter = srcMacAdressNicIdMap.end(); + SrcMacAdressNicIdMap::const_iterator findIter = srcMacAdressNicIdMap.find(srcMac); + if(findIter == endIter){ + srcMacAdressNicIdMap.insert(SrcMacAdressNicIdMapEntry(srcMac, interfaceId)); + } else if (interfaceId != findIter->second) { + result = true; + } + + srcMacAdressNicIdMapMutex.unlock(); + return result; + } } diff --git a/src/map/natmap.h b/src/natmap.h similarity index 86% rename from src/map/natmap.h rename to src/natmap.h index aff9af4..012e1b2 100644 --- a/src/map/natmap.h +++ b/src/natmap.h @@ -11,16 +11,18 @@ namespace otonat { static const Tins::IPv4Address zeroIp; - + class NatMap { public: typedef std::vector NatRangeList; typedef std::queue PduQueue; typedef std::pair IPv4AddressEntry; typedef std::map IpAdressMap; - typedef unsigned short int Checksum; - typedef std::list ChecksumList; - + typedef Tins::HWAddress<6> MacAddress; + typedef unsigned int NetworkInterfaceId; + typedef std::map SrcMacAdressNicIdMap; + typedef std::pair SrcMacAdressNicIdMapEntry; + NatMap() { } @@ -41,11 +43,11 @@ namespace otonat { Tins::PDU * popPduIncommingPduQueue(); void pushPduToOutgoingPduQueue(const Tins::PDU * pdu); Tins::PDU * popPduOutgoingPduQueue(); - void pushCheckSumToList(Checksum checksum); - + bool isOutgoingPdu(const Tins::PDU& pdu, NetworkInterfaceId interfaceId); + static Tins::PDU * popPduPduQueue(PduQueue & queue, std::mutex & mtx); static void pushPduToPduQueue(const Tins::PDU * pdu, PduQueue & queue, std::mutex & mtx); - + protected: private: @@ -65,12 +67,10 @@ namespace otonat { bool isIpInMyRanges(const Tins::IPv4Address & ipAddr) const; static bool isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList); void SendTranslatedArpRequest(const Tins::ARP * arp); - void popCheckSumToList(Checksum checksum); - bool containChecksumList(Checksum checksum); std::mutex incommingQueueMutex; std::mutex outgoingQueueMutex; - std::mutex checksumListMutex; - ChecksumList checksumList; + std::mutex srcMacAdressNicIdMapMutex; + SrcMacAdressNicIdMap srcMacAdressNicIdMap; }; }