diff --git a/src/PduSender.cpp b/src/PduSender.cpp index 303a1d2..64ee8d4 100644 --- a/src/PduSender.cpp +++ b/src/PduSender.cpp @@ -6,8 +6,7 @@ */ #include "PduSender.h" -#include -#include +#include "easylogging++.h" namespace otonat { @@ -36,12 +35,13 @@ namespace otonat { continue; } - std::cout << "send pdu:" << pdu->size() << std::endl; bool isIp = false; Tins::IPv4Address dstIp = zeroIp; + std::stringstream msgStream; const Tins::IP * ip = pdu->find_pdu(); if (ip != nullptr) { dstIp = ip->dst_addr(); + msgStream << "sending-ip: dst = " << dstIp << ", src= " << ip->src_addr() << ", checksum = " << ip->checksum(); isIp = true; } @@ -49,12 +49,15 @@ namespace otonat { const Tins::ARP * arp = pdu->find_pdu(); if (arp != nullptr) { dstIp = arp->target_ip_addr(); + msgStream << "sending-arp: dst = " << dstIp << ", src= " << arp->sender_ip_addr() << ", opcode = " << arp->opcode(); + }else{ + msgStream << "sending-unkown: "; } } for (NatRange & range : this->map->ranges) { if (range.calcIpRange(true).contains(dstIp)) { - std::cout << "send pdu:" << pdu->size() << std::endl; + LOG(INFO) << msgStream.str() << " (size = " << pdu->size() << ")"; sender.send(*pdu, range.interface); delete pdu; break; diff --git a/src/PduSniffer.cpp b/src/PduSniffer.cpp index cc9e9ba..5bdd86f 100644 --- a/src/PduSniffer.cpp +++ b/src/PduSniffer.cpp @@ -6,71 +6,84 @@ */ #include "PduSniffer.h" -#include -namespace otonat { +#include "easylogging++.h" - PduSniffer::PduSniffer(NatMap * map) { - this->map = map; - this->isRunnig = false; - config.set_promisc_mode(true); - config.set_immediate_mode(true); +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; } - PduSniffer::PduSniffer(const PduSniffer& orig) : snifferList(orig.snifferList), config(orig.config) { - this->map = orig.map; - this->isRunnig = orig.isRunnig; - } + this->snifferList.clear(); +} - PduSniffer::~PduSniffer() { - Stop(); - for (Tins::Sniffer * sniffer : snifferList) { - delete sniffer; - } +PduSniffer& PduSniffer::operator=(const PduSniffer& rhs) +{ + if (this == &rhs) return *this; // handle self assignment - this->snifferList.clear(); - } + this->map = rhs.map; + this->isRunnig = rhs.isRunnig; + this->config = rhs.config; + this->snifferList = rhs.snifferList; + return *this; +} - 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) { - if (map->isOutgoingPdu(pdu, interfaceId)){ - std::cout <<"outgoing:" << interfaceId<isRunnig; - } - - std::cout <<"incomming:" << interfaceId<map->pushPduToIncommingPduQueue(pdu.clone()); +bool PduSniffer::sniffPdu(const Tins::PDU& pdu) +{ + if (map->isOutgoingPdu(pdu, interfaceId)) + { + LOG(INFO) << "skip-outgoing: interface = " << interfaceName << "( id = " << interfaceId << ") (size = " << pdu.size() << ")"; return this->isRunnig; } - void PduSniffer::Start() { - this->isRunnig = true; - } - - 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; - } + LOG(INFO) << "sniff-incomming: interface = " << interfaceName << " (id = " << interfaceId << ") (size = " << pdu.size() << ")"; + this->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) +{ + interfaceId = interface.id(); + interfaceName = interface.name(); + LOG(INFO) << "create-sniffer: interface = " << interfaceName << " (id = " << interfaceId << ")"; + Start(); + Tins::Sniffer * sniffer = new Tins::Sniffer(interfaceName, 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 cf36632..777a6ec 100644 --- a/src/PduSniffer.h +++ b/src/PduSniffer.h @@ -33,6 +33,7 @@ namespace otonat { bool isRunnig; bool sniffPdu(const Tins::PDU &pdu); NatMap::NetworkInterfaceId interfaceId; + std::string interfaceName; }; } diff --git a/src/main.cpp b/src/main.cpp index 4564fe4..a00a277 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,3 @@ -#include #include #include #include "natmap.h" @@ -20,12 +19,16 @@ void delete_them(Container& c) c.clear(); } + + int main(int argc, char** argv) { if (argc < 2){ return 0; } - LOG(INFO) << "Hello, world"; + + el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format, "[%datetime] [%loc]: %msg"); + LOG(INFO) << "Hello, world, start 121nat"; otonat::NatMap::NatRangeList interfaceList; std::ifstream config_doc(argv[1], std::ifstream::binary); Json::Value root; diff --git a/src/natmap.cpp b/src/natmap.cpp index cc1250f..ae8ea50 100644 --- a/src/natmap.cpp +++ b/src/natmap.cpp @@ -1,434 +1,527 @@ #include "natmap.h" -#include -namespace otonat { +#include "easylogging++.h" - NatMap::NatMap(NatRangeList rangeList) : ranges(rangeList) { +namespace otonat +{ + +NatMap::NatMap(NatRangeList rangeList) : ranges(rangeList) +{ +} + +NatMap::~NatMap() +{ + ranges.clear(); + transMap.clear(); + reqIpMap.clear(); + this->incommingQueueMutex.lock(); + while (!incommingPduQueue.empty()) + { + incommingPduQueue.pop(); } - NatMap::~NatMap() { - ranges.clear(); - transMap.clear(); - reqIpMap.clear(); - this->incommingQueueMutex.lock(); - while (!incommingPduQueue.empty()) { - incommingPduQueue.pop(); - } + this->incommingQueueMutex.unlock(); - this->incommingQueueMutex.unlock(); - - this->outgoingQueueMutex.lock(); - while (!outgoingPduQueue.empty()) { - outgoingPduQueue.pop(); - } - - this->outgoingQueueMutex.unlock(); - - srcMacAdressNicIdMapMutex.lock(); - srcMacAdressNicIdMap.clear(); - srcMacAdressNicIdMapMutex.unlock(); + this->outgoingQueueMutex.lock(); + while (!outgoingPduQueue.empty()) + { + outgoingPduQueue.pop(); } - NatMap::NatMap(const NatMap& other) : ranges(other.ranges), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue),srcMacAdressNicIdMap(other.srcMacAdressNicIdMap) { + 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),srcMacAdressNicIdMap(other.srcMacAdressNicIdMap) +{ +} + +NatMap& NatMap::operator=(const NatMap& rhs) +{ + if (this == &rhs) return *this; // handle self assignment + + ranges = rhs.ranges; + transMap = rhs.transMap; + this->incommingQueueMutex.lock(); + incommingPduQueue = rhs.incommingPduQueue; + this->incommingQueueMutex.unlock(); + this->outgoingQueueMutex.lock(); + outgoingPduQueue = rhs.outgoingPduQueue; + this->outgoingQueueMutex.unlock(); + this->srcMacAdressNicIdMapMutex.lock(); + this->srcMacAdressNicIdMap = rhs.srcMacAdressNicIdMap; + this->srcMacAdressNicIdMapMutex.unlock(); + return *this; +} + +void NatMap::handlePdu(const Tins::PDU * pdu) +{ + if (pdu == nullptr) + { + LOG(INFO) << "pdu is null"; + return; } - NatMap& NatMap::operator=(const NatMap& rhs) { - if (this == &rhs) return *this; // handle self assignment - - ranges = rhs.ranges; - transMap = rhs.transMap; - this->incommingQueueMutex.lock(); - incommingPduQueue = rhs.incommingPduQueue; - this->incommingQueueMutex.unlock(); - this->outgoingQueueMutex.lock(); - outgoingPduQueue = rhs.outgoingPduQueue; - this->outgoingQueueMutex.unlock(); - this->srcMacAdressNicIdMapMutex.lock(); - this->srcMacAdressNicIdMap = rhs.srcMacAdressNicIdMap; - this->srcMacAdressNicIdMapMutex.unlock(); - return *this; + Tins::PDU * pduCopy = pdu->clone(); + delete pdu; + Tins::ARP * arp = pduCopy->find_pdu(); + if (arp != nullptr) + { + LOG(INFO) << "handle-arp: dst = " << arp->target_ip_addr() << ", src= " << arp->sender_ip_addr() << ", opcode = " << arp->opcode() << " (size = " << pduCopy->size() <<" )"; + if (handleArp(arp)) + { + this->pushPduToOutgoingPduQueue(pduCopy); + } + return; } - void NatMap::handlePdu(const Tins::PDU * pdu) { - std::cout << "handle pdu:" << pdu->size() << std::endl; - if (pdu == nullptr) { - return; - } - - Tins::PDU * pduCopy = pdu->clone(); - delete pdu; - Tins::ARP * arp = pduCopy->find_pdu(); - if (arp != nullptr) { - if (handleArp(arp)) { - this->pushPduToOutgoingPduQueue(pduCopy); - } - return; - } - - Tins::IP * ip = pduCopy->find_pdu(); - if (ip != nullptr && handleIp(ip, pduCopy)) { - + Tins::IP * ip = pduCopy->find_pdu(); + if (ip != nullptr) + { + LOG(INFO) << "handle-ip: dst = " << ip->dst_addr() << ", src= " << ip->src_addr() << ", checksum = " << ip->checksum() << " (size = " << pduCopy->size() << ")"; + if(handleIp(ip, pduCopy)) + { this->pushPduToOutgoingPduQueue(pduCopy); } } - - bool NatMap::handleIp(Tins::IP * ip, const Tins::PDU * originPDU) { - if (isForMeOrFromMeIp(ip)) { - return false; - } - - const Tins::IPv4Address originDstIp = ip->dst_addr(); - if (!isIpInMyRanges(originDstIp)) { - return false; - } - - IpAdressMap::iterator transIpIter = transMap.find(originDstIp); - if (transIpIter != transMap.end()) { - // handle know traslation ip - const Tins::IPv4Address transDstIp = transIpIter->second; - TranslateIpPacket(ip, transDstIp); - IpAdressMap::iterator transDstIpIter = transMap.find(transDstIp); - if (transDstIpIter == transMap.end()) { - transMap.insert(IPv4AddressEntry(transDstIp, originDstIp)); - } else if (transDstIpIter->second != originDstIp) { - transMap[transDstIp] = originDstIp; - } - - return true; - } else { - const Tins::EthernetII * eth = originPDU->find_pdu(); - if (eth != nullptr) { - - Tins::EthernetII fakeArp = Tins::ARP::make_arp_request(ip->dst_addr(), ip->src_addr(), eth->src_addr()); - SendTranslatedArpRequest(fakeArp.find_pdu()); - } - - return false; - } + else + { + LOG(INFO) << "handle-unkown: (size = " << pduCopy->size() << ")"; } +} - void NatMap::TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transDstIp) { - - // set translated dst address - ip->dst_addr(transDstIp); - - // translate src adress - const Tins::IPv4Address originSrc = ip->src_addr(); - - IpAdressMap::const_iterator transIpIter = transMap.find(originSrc); - Tins::IPv4Address transSrcAttr; - if (transIpIter != transMap.end()) { - // set translated src address - transSrcAttr = transIpIter->second; - } else { - - transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transDstIp, ranges); - } - - ip->src_addr(transSrcAttr); - } - - Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & otherTransSameRangeIp, NatRangeList & rangeList) { - // calc translated ip address for first up and not same interfaces - for (NatRange & range : rangeList) { - // insert or update translated ip address - const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); - if (!interfaceInfo.is_up) { - continue; - } - - const Tins::IPv4Range ipRange = range.calcIpRange(true); - if (!ipRange.contains(otherTransSameRangeIp)) { - - continue; - } - - return InsertOrUdpateTranslateIpAddress(originIp, range); - } - - return zeroIp; - } - - Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const NatRange & range) { - // translated ip address - const Tins::IPv4Address transAddr = range.mapIPv4Addres(originIp, false); - - // insert forward translation - InsertOrUdpateTranslateIpAddress(originIp, transAddr); - - // insert or update backward translation - InsertOrUdpateTranslateIpAddress(transAddr, originIp); - - return transAddr; - } - - void NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp) { - IpAdressMap::const_iterator transIpIter = transMap.find(transIp); - if (transIpIter != transMap.end()) { - transMap[transIp] = originIp; - } else { - - transMap.insert(IPv4AddressEntry(transIp, originIp)); - } - } - - bool NatMap::handleArp(Tins::ARP * arp) { - if (isForMeOrFromMeArp(arp)) { - return false; - } - - const Tins::IPv4Address & originDstIp = arp->target_ip_addr(); - if (!isIpInMyRanges(originDstIp)) { - return false; - } - - switch (arp->opcode()) { - case Tins::ARP::REQUEST: - return this->handleArpReq(arp); - case Tins::ARP::REPLY: - return this->handleArpReply(arp); - - default: - return false; - } - } - - bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) const { - - return isForMeOrFromMeIp(ip, ranges); - } - - bool NatMap::isForMeOrFromMeArp(const Tins::ARP * arp) const { - Tins::IP fakeIp(arp->target_ip_addr(), arp->sender_ip_addr()); - - return isForMeOrFromMeIp(&fakeIp); - } - - bool NatMap::isForMeOrFromMeIp(const Tins::IP * ip, const NatRangeList & rangeList) { - const Tins::IPv4Address & srcAddr = ip->src_addr(); - const Tins::IPv4Address & dstAddr = ip->dst_addr(); - for (NatRange range : rangeList) { - const Tins::IPv4Address & interfaceAddr = range.interface.info().ip_addr; - if (srcAddr == interfaceAddr || dstAddr == interfaceAddr) { - - return true; - } - } +bool NatMap::handleIp(Tins::IP * ip, const Tins::PDU * originPDU) +{ + if (isForMeOrFromMeIp(ip)) + { return false; } - bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) const { - - return isIpInMyRanges(ipAddr, ranges); + const Tins::IPv4Address originDstIp = ip->dst_addr(); + if (!isIpInMyRanges(originDstIp)) + { + return false; } - bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList) { - for (NatRange range : rangeList) { - if (range.calcIpRange(false).contains(ipAddr)) { + IpAdressMap::iterator transIpIter = transMap.find(originDstIp); + if (transIpIter != transMap.end()) + { + // handle know traslation ip + const Tins::IPv4Address transDstIp = transIpIter->second; + TranslateIpPacket(ip, transDstIp); + IpAdressMap::iterator transDstIpIter = transMap.find(transDstIp); + if (transDstIpIter == transMap.end()) + { + transMap.insert(IPv4AddressEntry(transDstIp, originDstIp)); + } + else if (transDstIpIter->second != originDstIp) + { + transMap[transDstIp] = originDstIp; + } - return true; - } + return true; + } + else + { + const Tins::EthernetII * eth = originPDU->find_pdu(); + if (eth != nullptr) + { + + Tins::EthernetII fakeArp = Tins::ARP::make_arp_request(ip->dst_addr(), ip->src_addr(), eth->src_addr()); + SendTranslatedArpRequest(fakeArp.find_pdu()); } return false; } +} - bool NatMap::handleArpReq(Tins::ARP* arp) { - const Tins::IPv4Address targetIp = arp->target_ip_addr(); - IpAdressMap::const_iterator transTargetIpIter = this->transMap.find(targetIp); - if (transTargetIpIter == transMap.end()) { - SendTranslatedArpRequest(arp); - return false; +void NatMap::TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transDstIp) +{ + + // set translated dst address + ip->dst_addr(transDstIp); + + // translate src adress + const Tins::IPv4Address originSrc = ip->src_addr(); + + IpAdressMap::const_iterator transIpIter = transMap.find(originSrc); + Tins::IPv4Address transSrcAttr; + if (transIpIter != transMap.end()) + { + // set translated src address + transSrcAttr = transIpIter->second; + } + else + { + + transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transDstIp, ranges); + } + + ip->src_addr(transSrcAttr); +} + +Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & otherTransSameRangeIp, NatRangeList & rangeList) +{ + // calc translated ip address for first up and not same interfaces + for (NatRange & range : rangeList) + { + // insert or update translated ip address + const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); + if (!interfaceInfo.is_up) + { + continue; } - const Tins::IPv4Address transTargetIp = transTargetIpIter->second; - arp->target_ip_addr(transTargetIp); - IpAdressMap::const_iterator transSenderIpIter = this->transMap.find(arp->sender_ip_addr()); - if (transSenderIpIter != transMap.end()) { - arp->sender_ip_addr(transSenderIpIter->second); - this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); + const Tins::IPv4Range ipRange = range.calcIpRange(true); + if (!ipRange.contains(otherTransSameRangeIp)) + { + + continue; + } + + return InsertOrUdpateTranslateIpAddress(originIp, range); + } + + return zeroIp; +} + +Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const NatRange & range) +{ + // translated ip address + const Tins::IPv4Address transAddr = range.mapIPv4Addres(originIp, false); + + // insert forward translation + InsertOrUdpateTranslateIpAddress(originIp, transAddr); + + // insert or update backward translation + InsertOrUdpateTranslateIpAddress(transAddr, originIp); + + return transAddr; +} + +void NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp) +{ + IpAdressMap::const_iterator transIpIter = transMap.find(transIp); + if (transIpIter != transMap.end()) + { + transMap[transIp] = originIp; + } + else + { + + transMap.insert(IPv4AddressEntry(transIp, originIp)); + } +} + +bool NatMap::handleArp(Tins::ARP * arp) +{ + if (isForMeOrFromMeArp(arp)) + { + return false; + } + + const Tins::IPv4Address & originDstIp = arp->target_ip_addr(); + if (!isIpInMyRanges(originDstIp)) + { + return false; + } + + switch (arp->opcode()) + { + case Tins::ARP::REQUEST: + return this->handleArpReq(arp); + case Tins::ARP::REPLY: + return this->handleArpReply(arp); + + default: + return false; + } +} + +bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) const +{ + + return isForMeOrFromMeIp(ip, ranges); +} + +bool NatMap::isForMeOrFromMeArp(const Tins::ARP * arp) const +{ + Tins::IP fakeIp(arp->target_ip_addr(), arp->sender_ip_addr()); + + return isForMeOrFromMeIp(&fakeIp); +} + +bool NatMap::isForMeOrFromMeIp(const Tins::IP * ip, const NatRangeList & rangeList) +{ + const Tins::IPv4Address & srcAddr = ip->src_addr(); + const Tins::IPv4Address & dstAddr = ip->dst_addr(); + for (NatRange range : rangeList) + { + const Tins::IPv4Address & interfaceAddr = range.interface.info().ip_addr; + if (srcAddr == interfaceAddr || dstAddr == interfaceAddr) + { return true; } + } + return false; +} - return handleArpAndTranslateSenderIp(arp); +bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) const +{ + + return isIpInMyRanges(ipAddr, ranges); +} + +bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList) +{ + for (NatRange range : rangeList) + { + if (range.calcIpRange(false).contains(ipAddr)) + { + + return true; + } } - bool NatMap::handleArpReply(Tins::ARP* arp) { - const Tins::IPv4Address targetIp = arp->target_ip_addr(); - const Tins::IPv4Address transTargetIp = TranslateArpIp(targetIp); - if (transTargetIp == zeroIp) { - return false; - } + return false; +} - const Tins::IPv4Address senderIp = arp->sender_ip_addr(); - const Tins::IPv4Address transSenderIp = TranslateArpIp(senderIp); - if (transSenderIp == zeroIp) { - return false; - } +bool NatMap::handleArpReq(Tins::ARP* arp) +{ + const Tins::IPv4Address targetIp = arp->target_ip_addr(); + IpAdressMap::const_iterator transTargetIpIter = this->transMap.find(targetIp); + if (transTargetIpIter == transMap.end()) + { + SendTranslatedArpRequest(arp); + return false; + } + + const Tins::IPv4Address transTargetIp = transTargetIpIter->second; + arp->target_ip_addr(transTargetIp); + IpAdressMap::const_iterator transSenderIpIter = this->transMap.find(arp->sender_ip_addr()); + if (transSenderIpIter != transMap.end()) + { + arp->sender_ip_addr(transSenderIpIter->second); + this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); - arp->target_ip_addr(transTargetIp); - arp->sender_ip_addr(transSenderIp); return true; } - const Tins::IPv4Address NatMap::TranslateArpIp(const Tins::IPv4Address & arpIp) { - Tins::IPv4Address transArpIp; - IpAdressMap::const_iterator transArpIpIter = this->transMap.find(arpIp); - if (transArpIpIter == transMap.end()) { - IpAdressMap::const_iterator transReqArpIpIter = this->reqIpMap.find(arpIp); - if (transReqArpIpIter == reqIpMap.end()) { - return zeroIp; - } - - transArpIp = transReqArpIpIter->second; - this->InsertOrUdpateTranslateIpAddress(arpIp, transArpIp); - this->InsertOrUdpateTranslateIpAddress(transArpIp, arpIp); - this->reqIpMap.erase(transReqArpIpIter); - - return transArpIp; - } - - return transArpIpIter->second; - } - - bool NatMap::handleArpAndTranslateSenderIp(Tins::ARP* arp) { - for (NatRange & range : this->ranges) { - const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); - if (!interfaceInfo.is_up) { - continue; - } - - const Tins::IPv4Range ipRange = range.calcIpRange(true); - if (!ipRange.contains(arp->target_ip_addr())) { - continue; - } - - const Tins::IPv4Address senderIp = arp->sender_ip_addr(); - const Tins::IPv4Address transSenderIp = range.mapIPv4Addres(senderIp, true); - arp->sender_ip_addr(transSenderIp); - - IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(transSenderIp); - if (transSenderIpReqIter == reqIpMap.end()) { - - this->reqIpMap.insert(IPv4AddressEntry(transSenderIp, senderIp)); - } - - return true; - } + return handleArpAndTranslateSenderIp(arp); +} +bool NatMap::handleArpReply(Tins::ARP* arp) +{ + const Tins::IPv4Address targetIp = arp->target_ip_addr(); + const Tins::IPv4Address transTargetIp = TranslateArpIp(targetIp); + if (transTargetIp == zeroIp) + { return false; } - void NatMap::SendTranslatedArpRequest(const Tins::ARP * arp) { - const Tins::IPv4Address targetIp = arp->target_ip_addr(); - for (NatRange & range : this->ranges) { - const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); - if (!interfaceInfo.is_up) { - continue; - } - - const Tins::IPv4Range ipRange = range.calcIpRange(true); - if (ipRange.contains(targetIp)) { - continue; - } - - const Tins::IPv4Address senderIp = arp->sender_ip_addr(); - const Tins::IPv4Address transSenderIp = range.mapIPv4Addres(senderIp, false); - const Tins::IPv4Address transTargetIp = range.mapIPv4Addres(targetIp, false); - IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(transSenderIp); - if (transSenderIpReqIter == reqIpMap.end()) { - this->reqIpMap.insert(IPv4AddressEntry(transSenderIp, senderIp)); - } - - IpAdressMap::const_iterator transTargetIpReqIter = this->reqIpMap.find(transTargetIp); - if (transTargetIpReqIter == reqIpMap.end()) { - - this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); - } - - const Tins::EthernetII transArp = Tins::ARP::make_arp_request(transTargetIp, transSenderIp, arp->sender_hw_addr()); - this->pushPduToOutgoingPduQueue(transArp.clone()); - } + const Tins::IPv4Address senderIp = arp->sender_ip_addr(); + const Tins::IPv4Address transSenderIp = TranslateArpIp(senderIp); + if (transSenderIp == zeroIp) + { + return false; } - void NatMap::pushPduToIncommingPduQueue(const Tins::PDU* pdu) { + arp->target_ip_addr(transTargetIp); + arp->sender_ip_addr(transSenderIp); + return true; +} - pushPduToPduQueue(pdu, this->incommingPduQueue, this ->incommingQueueMutex); - } - - Tins::PDU * NatMap::popPduIncommingPduQueue() { - - return popPduPduQueue(this->incommingPduQueue, this->incommingQueueMutex); - } - - void NatMap::pushPduToOutgoingPduQueue(const Tins::PDU* pdu) { - - pushPduToPduQueue(pdu, this->outgoingPduQueue, this->outgoingQueueMutex); - } - - Tins::PDU * NatMap::popPduOutgoingPduQueue() { - - return popPduPduQueue(this->outgoingPduQueue, this->outgoingQueueMutex); - } - - Tins::PDU * NatMap::popPduPduQueue(PduQueue & queue, std::mutex & mtx) { - mtx.lock(); - if (queue.empty()) { - mtx.unlock(); - return nullptr; +const Tins::IPv4Address NatMap::TranslateArpIp(const Tins::IPv4Address & arpIp) +{ + Tins::IPv4Address transArpIp; + IpAdressMap::const_iterator transArpIpIter = this->transMap.find(arpIp); + if (transArpIpIter == transMap.end()) + { + IpAdressMap::const_iterator transReqArpIpIter = this->reqIpMap.find(arpIp); + if (transReqArpIpIter == reqIpMap.end()) + { + return zeroIp; } - const Tins::PDU * result = queue.front(); - Tins::PDU * outPut = result->clone(); - queue.pop(); - mtx.unlock(); - delete result; + transArpIp = transReqArpIpIter->second; + this->InsertOrUdpateTranslateIpAddress(arpIp, transArpIp); + this->InsertOrUdpateTranslateIpAddress(transArpIp, arpIp); + this->reqIpMap.erase(transReqArpIpIter); - return outPut; + return transArpIp; } - void NatMap::pushPduToPduQueue(const Tins::PDU* pdu, PduQueue& queue, std::mutex& mtx) { + return transArpIpIter->second; +} - mtx.lock(); - 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; - } - - bool NatMap::isOutgoingPdu(const Tins::PDU& pdu, NetworkInterfaceId interfaceId){ - const Tins::EthernetII * ethFrame = pdu.find_pdu(); - if (ethFrame == nullptr){ - return false; +bool NatMap::handleArpAndTranslateSenderIp(Tins::ARP* arp) +{ + for (NatRange & range : this->ranges) + { + const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); + if (!interfaceInfo.is_up) + { + continue; } - 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; + const Tins::IPv4Range ipRange = range.calcIpRange(true); + if (!ipRange.contains(arp->target_ip_addr())) + { + continue; } - srcMacAdressNicIdMapMutex.unlock(); - return result; + const Tins::IPv4Address senderIp = arp->sender_ip_addr(); + const Tins::IPv4Address transSenderIp = range.mapIPv4Addres(senderIp, true); + arp->sender_ip_addr(transSenderIp); + + IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(transSenderIp); + if (transSenderIpReqIter == reqIpMap.end()) + { + + this->reqIpMap.insert(IPv4AddressEntry(transSenderIp, senderIp)); + } + + return true; + } + + return false; +} + +void NatMap::SendTranslatedArpRequest(const Tins::ARP * arp) +{ + const Tins::IPv4Address targetIp = arp->target_ip_addr(); + for (NatRange & range : this->ranges) + { + const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); + if (!interfaceInfo.is_up) + { + continue; + } + + const Tins::IPv4Range ipRange = range.calcIpRange(true); + if (ipRange.contains(targetIp)) + { + continue; + } + + const Tins::IPv4Address senderIp = arp->sender_ip_addr(); + const Tins::IPv4Address transSenderIp = range.mapIPv4Addres(senderIp, false); + const Tins::IPv4Address transTargetIp = range.mapIPv4Addres(targetIp, false); + IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(transSenderIp); + if (transSenderIpReqIter == reqIpMap.end()) + { + this->reqIpMap.insert(IPv4AddressEntry(transSenderIp, senderIp)); + } + + IpAdressMap::const_iterator transTargetIpReqIter = this->reqIpMap.find(transTargetIp); + if (transTargetIpReqIter == reqIpMap.end()) + { + + this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); + } + + const Tins::EthernetII transArp = Tins::ARP::make_arp_request(transTargetIp, transSenderIp, arp->sender_hw_addr()); + this->pushPduToOutgoingPduQueue(transArp.clone()); } } + +void NatMap::pushPduToIncommingPduQueue(const Tins::PDU* pdu) +{ + + pushPduToPduQueue(pdu, this->incommingPduQueue, this ->incommingQueueMutex); +} + +Tins::PDU * NatMap::popPduIncommingPduQueue() +{ + + return popPduPduQueue(this->incommingPduQueue, this->incommingQueueMutex); +} + +void NatMap::pushPduToOutgoingPduQueue(const Tins::PDU* pdu) +{ + + pushPduToPduQueue(pdu, this->outgoingPduQueue, this->outgoingQueueMutex); +} + +Tins::PDU * NatMap::popPduOutgoingPduQueue() +{ + + return popPduPduQueue(this->outgoingPduQueue, this->outgoingQueueMutex); +} + +Tins::PDU * NatMap::popPduPduQueue(PduQueue & queue, std::mutex & mtx) +{ + mtx.lock(); + if (queue.empty()) + { + mtx.unlock(); + return nullptr; + } + + const Tins::PDU * result = queue.front(); + Tins::PDU * outPut = result->clone(); + queue.pop(); + mtx.unlock(); + delete result; + + return outPut; +} + +void NatMap::pushPduToPduQueue(const Tins::PDU* pdu, PduQueue& queue, std::mutex& mtx) +{ + + mtx.lock(); + 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; +} + +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; +} +}