addlogging

This commit is contained in:
stubbfel
2016-03-09 22:47:39 +01:00
parent 449a6571ba
commit eb1914bf1e
5 changed files with 552 additions and 439 deletions

View File

@@ -6,8 +6,7 @@
*/
#include "PduSender.h"
#include <iostream>
#include <algorithm>
#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<Tins::IP>();
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<Tins::ARP>();
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;

View File

@@ -6,71 +6,84 @@
*/
#include "PduSniffer.h"
#include <iostream>
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<<std::endl;
return this->isRunnig;
}
std::cout <<"incomming:" << interfaceId<<std::endl;
std::cout <<"sniff pdu:" << pdu.size() <<std::endl;
this->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<<std::endl;
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;
}
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;
}
}

View File

@@ -33,6 +33,7 @@ namespace otonat {
bool isRunnig;
bool sniffPdu(const Tins::PDU &pdu);
NatMap::NetworkInterfaceId interfaceId;
std::string interfaceName;
};
}

View File

@@ -1,4 +1,3 @@
#include <iostream>
#include <tins/tins.h>
#include <thread>
#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;

View File

@@ -1,434 +1,527 @@
#include "natmap.h"
#include <iostream>
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<Tins::ARP>();
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<Tins::ARP>();
if (arp != nullptr) {
if (handleArp(arp)) {
this->pushPduToOutgoingPduQueue(pduCopy);
}
return;
}
Tins::IP * ip = pduCopy->find_pdu<Tins::IP>();
if (ip != nullptr && handleIp(ip, pduCopy)) {
Tins::IP * ip = pduCopy->find_pdu<Tins::IP>();
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<Tins::EthernetII>();
if (eth != nullptr) {
Tins::EthernetII fakeArp = Tins::ARP::make_arp_request(ip->dst_addr(), ip->src_addr(), eth->src_addr());
SendTranslatedArpRequest(fakeArp.find_pdu<Tins::ARP>());
}
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<Tins::EthernetII>();
if (eth != nullptr)
{
Tins::EthernetII fakeArp = Tins::ARP::make_arp_request(ip->dst_addr(), ip->src_addr(), eth->src_addr());
SendTranslatedArpRequest(fakeArp.find_pdu<Tins::ARP>());
}
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<Tins::EthernetII>();
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<Tins::EthernetII>();
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;
}
}