diff --git a/src/PduSender.cpp b/src/PduSender.cpp index d935da6..5a6d6ae 100644 --- a/src/PduSender.cpp +++ b/src/PduSender.cpp @@ -6,13 +6,16 @@ */ #include "PduSender.h" +#include +#include + namespace otonat { PduSender::PduSender(NatMap * map) { this->map = map; } - PduSender::PduSender(const PduSender& orig) { + PduSender::PduSender(const PduSender& orig) : checksumList(orig.checksumList) { this->map = orig.map; } @@ -20,7 +23,7 @@ namespace otonat { if (this == &rhs) return *this; // handle self assignment this->map = rhs.map; - + this->checksumList = rhs.checksumList; return *this; } @@ -34,26 +37,49 @@ namespace otonat { continue; } + std::cout << "send pdu:" << pdu->size() << std::endl; + Tins::IPv4Address dstIp = zeroIp; const Tins::ARP * arp = pdu->find_pdu(); + bool isArp = false; if (arp != nullptr) { dstIp = arp->target_ip_addr(); + isArp = true; } - - if (dstIp != zeroIp) { + + if (!isArp) { const Tins::IP * ip = pdu->find_pdu(); if (ip != nullptr) { dstIp = ip->dst_addr(); + + unsigned short int checkSum = ip->checksum(); + ChecksumList::const_iterator endIter = this->checksumList.end(); + ChecksumList::const_iterator beginIter = this->checksumList.begin(); + ChecksumList::const_iterator findIter = std::find(beginIter, endIter, checkSum); + if (endIter == findIter) { + this->checksumList.push_back(checkSum); + if (this->checksumList.size() > 10) { + this->checksumList.pop_front(); + } + } else { + continue; + } } } - + for (NatRange & range : this->map->ranges) { - if(range.calcIpRange(true).contains(dstIp)){ + if (range.calcIpRange(true).contains(dstIp)) { + std::cout << "send pdu:" << pdu->size() << std::endl; sender.send(*pdu, range.interface); delete pdu; - return; + break; } } } } + + std::thread * PduSender::SendPdusFromQueueThread() { + std::thread * newThread = new std::thread(std::bind(&PduSender::SendPdusFromQueue, this)); + return newThread; + } } diff --git a/src/PduSender.h b/src/PduSender.h index 776b877..b741533 100644 --- a/src/PduSender.h +++ b/src/PduSender.h @@ -10,18 +10,24 @@ #include "map/natmap.h" #include +#include +#include namespace otonat { class PduSender { public: + typedef std::list ChecksumList; + PduSender(NatMap * map); PduSender(const PduSender& orig); PduSender& operator=(const PduSender& rhs); virtual ~PduSender(); NatMap * map; - + ChecksumList checksumList; void SendPdusFromQueue(); + + std::thread * SendPdusFromQueueThread(); private: Tins::PacketSender sender; }; diff --git a/src/PduSniffer.cpp b/src/PduSniffer.cpp index f1a05d7..6257d3c 100644 --- a/src/PduSniffer.cpp +++ b/src/PduSniffer.cpp @@ -6,7 +6,7 @@ */ #include "PduSniffer.h" - +#include namespace otonat { PduSniffer::PduSniffer(NatMap * map) { @@ -41,6 +41,7 @@ namespace otonat { } bool PduSniffer::sniffPdu(const Tins::PDU& pdu) { + std::cout <<"sniff pdu:" << pdu.size() <map->pushPduToIncommingPduQueue(pdu.clone()); return this->isRunnig; } @@ -56,7 +57,7 @@ namespace otonat { 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)); + sniffer->sniff_loop(std::bind(&PduSniffer::sniffPdu, this, std::placeholders::_1)); this->snifferList.push_back(sniffer); } diff --git a/src/main.cpp b/src/main.cpp index 7205cd8..61ac28c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,119 +1,30 @@ #include #include #include - - -using namespace std; -using namespace Tins; - -const IPv4Address calcAdress(const IPv4Address & ip) -{ - IPv4Address incommingIp = IPv4Address(ip); - IPv4Address networkStartIp = IPv4Address("10.0.0.0"); - IPv4Address subnetp = IPv4Address("255.255.240.0"); - - uint32_t ipInt = (incommingIp & ~subnetp) | networkStartIp; - IPv4Address result = IPv4Address(ipInt); - std::cout << "Destination address: " << incommingIp << std::endl; - std::cout << "new Destination address: " << result<< std::endl; - std::cout << "####"<< std::endl; - return result; -} - -bool arpm(const PDU &pdu) -{ - // Retrieve the ARP layer - const ARP &arp = pdu.rfind_pdu(); - std::cout << arp.opcode()<< std::endl; - if (arp.opcode() == ARP::REQUEST) - { - PacketSender sender; - const NetworkInterface iface("vboxnet0"); - EthernetII req = ARP::make_arp_request(calcAdress(arp.target_ip_addr()),"10.0.3.42","08:00:27:d3:ef:1e"); - sender.send(req, iface); - } - - return true; -} - -bool arpm2(const PDU &pdu) -{ - // Retrieve the ARP layer - const ARP &arp = pdu.rfind_pdu(); - - std::cout << arp.opcode()<< std::endl; - if (arp.opcode() == ARP::REPLY) - { - PacketSender sender; - const NetworkInterface iface("vboxnet1"); - EthernetII rep = ARP::make_arp_reply("172.16.3.42","172.17.0.20","08:00:27:d3:ef:1e","08:00:27:29:f2:55"); - sender.send(rep, iface); - } else if (arp.target_ip_addr().to_string() == "10.0.3.42") - { - PacketSender sender; - const NetworkInterface iface("vboxnet0"); - EthernetII rep = ARP::make_arp_reply("10.0.0.20","10.0.3.42","08:00:27:29:f2:55","08:00:27:d3:ef:1e"); - sender.send(rep, iface); - } - - return true; -} - -bool doo(PDU &some_pdu) -{ - //PacketWriter writer("before.pcap", PacketWriter::ETH2); - //writer.write(some_pdu); - - IP &ip = some_pdu.rfind_pdu(); - ip.dst_addr(calcAdress(ip.dst_addr())); - ip.src_addr("10.0.3.42"); - //writer = PacketWriter("after.pcap", PacketWriter::ETH2); - //writer.write(some_pdu); - PacketSender sender; - some_pdu.send(sender,"vboxnet0"); - return true; -} - - - -void test1() -{ - SnifferConfiguration config; - config.set_promisc_mode(true); - config.set_immediate_mode(true); - //config.set_filter("ip src 192.168.0.100"); - Sniffer sniffer("vboxnet1", config); - sniffer.sniff_loop(arpm); -} - -void test2() -{ - SnifferConfiguration config; - config.set_promisc_mode(true); - config.set_immediate_mode(true); - //config.set_filter("ip src 192.168.0.100"); - Sniffer sniffer("vboxnet0", config); - sniffer.sniff_loop(arpm2); -} - -void test3() -{ - SnifferConfiguration config; - config.set_promisc_mode(true); - config.set_immediate_mode(true); - //config.set_filter("ip src 192.168.0.100"); - Sniffer sniffer("vboxnet1", config); - sniffer.sniff_loop(doo); -} +#include "map/natmap.h" +#include "PduSniffer.h" +#include "PduSender.h" int main() { - thread t1(test1); - thread t2(test2); - thread t3(test3); - t1.join(); - t2.join(); - t3.join(); + Tins::NetworkInterface net1("vboxnet0"); + Tins::NetworkInterface net2("vboxnet1"); + otonat::NatRange range1(net1, "10.0.0.0", "255.255.240.0"); + otonat::NatRange range2(net2, "172.27.0.0", "255.255.0.0"); + otonat::NatMap::NatRangeList list; + list.push_back(range1); + list.push_back(range2); + otonat::NatMap natMap = otonat::NatMap(list); + otonat::PduSniffer sniffer(&natMap); + otonat::PduSender sender(&natMap); + std::thread * mapThread = natMap.translateThread(); + std::thread * senderThread = sender.SendPdusFromQueueThread(); + std::thread * snifferThread1 = sniffer.SniffInterfaceInNewThread(net1); + std::thread * snifferThread2 = sniffer.SniffInterfaceInNewThread(net2); + mapThread->join(); + senderThread->join(); + snifferThread1->join(); + snifferThread2->join(); return 0; } diff --git a/src/map/natmap.cpp b/src/map/natmap.cpp index 6b12c08..4cc0d98 100644 --- a/src/map/natmap.cpp +++ b/src/map/natmap.cpp @@ -1,5 +1,5 @@ #include "natmap.h" - +#include namespace otonat { NatMap::NatMap(NatRangeList rangeList) : ranges(rangeList) { @@ -13,14 +13,14 @@ namespace otonat { while (!incommingPduQueue.empty()) { incommingPduQueue.pop(); } - + this->incommingQueueMutex.unlock(); - + this->outgoingQueueMutex.lock(); while (!outgoingPduQueue.empty()) { outgoingPduQueue.pop(); } - + this->outgoingQueueMutex.unlock(); } @@ -42,6 +42,7 @@ namespace otonat { } void NatMap::handlePdu(const Tins::PDU * pdu) { + std::cout << "handle pdu:" << pdu->size() << std::endl; if (pdu == nullptr) { return; } @@ -219,6 +220,11 @@ 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); @@ -230,7 +236,8 @@ namespace otonat { IpAdressMap::const_iterator transSenderIpIter = this->transMap.find(arp->sender_ip_addr()); if (transSenderIpIter != transMap.end()) { arp->sender_ip_addr(transSenderIpIter->second); - return false; + this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); + return true; } return handleArpAndTranslateSenderIp(arp); @@ -238,6 +245,11 @@ 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; @@ -349,11 +361,11 @@ namespace otonat { Tins::PDU * NatMap::popPduPduQueue(PduQueue & queue, std::mutex & mtx) { mtx.lock(); - if(queue.empty()){ + if (queue.empty()) { mtx.unlock(); return nullptr; } - + const Tins::PDU * result = queue.front(); Tins::PDU * outPut = result->clone(); queue.pop(); @@ -367,4 +379,20 @@ namespace otonat { queue.push(pdu); mtx.unlock(); } + + void NatMap::translate() { + while (true) { + Tins::PDU * pdu = this->popPduIncommingPduQueue(); + if (pdu == nullptr) { + continue; + } + + this->handlePdu(pdu); + } + } + + std::thread * NatMap::translateThread() { + std::thread * newThread = new std::thread(std::bind(&NatMap::translate, this)); + return newThread; + } } diff --git a/src/map/natmap.h b/src/map/natmap.h index bd9388f..97a3738 100644 --- a/src/map/natmap.h +++ b/src/map/natmap.h @@ -7,6 +7,7 @@ #include #include "NatRange.h" #include +#include namespace otonat { static const Tins::IPv4Address zeroIp; @@ -30,6 +31,8 @@ namespace otonat { IpAdressMap reqIpMap; PduQueue incommingPduQueue; PduQueue outgoingPduQueue; + void translate(); + std::thread * translateThread(); void handlePdu(const Tins::PDU * pdu); void pushPduToIncommingPduQueue(const Tins::PDU * pdu); Tins::PDU * popPduIncommingPduQueue();