check outgoing packet , depends of source mac

This commit is contained in:
stubbfel
2016-03-04 01:45:57 +01:00
parent 9967794354
commit dccc639617
14 changed files with 174 additions and 154 deletions

View File

@@ -1,5 +0,0 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES} ${TESTOBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif

View File

@@ -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)

View File

@@ -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
)

View File

@@ -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<Tins::IP>();
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;

View File

@@ -8,7 +8,7 @@
#ifndef PDUSENDER_H
#define PDUSENDER_H
#include "map/natmap.h"
#include "natmap.h"
#include <tins/tins.h>
#include <thread>
#include <list>

View File

@@ -41,6 +41,12 @@ namespace otonat {
}
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());
return this->isRunnig;
@@ -55,6 +61,8 @@ namespace otonat {
}
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));

74
src/PduSniffer.cpp~ Normal file
View File

@@ -0,0 +1,74 @@
/*
* File: PduSniffer.cpp
* Author: dev
*
* Created on 29. September 2015, 21:29
*/
#include "PduSniffer.h"
#include <iostream>
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<Tins::EthernetII>();
if (ethFrame == nullptr){
return this->isRunnig;
}
ethFrame->src_addr();
std::cout <<"sniff pdu:" << pdu.size() <<std::endl;
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) {
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;
}
}

View File

@@ -8,7 +8,7 @@
#ifndef PDUSNIFFER_H
#define PDUSNIFFER_H
#include "map/natmap.h"
#include "natmap.h"
#include <tins/tins.h>
#include <thread>
@@ -32,6 +32,7 @@ namespace otonat {
Tins::SnifferConfiguration config;
bool isRunnig;
bool sniffPdu(const Tins::PDU &pdu);
NatMap::NetworkInterfaceId interfaceId;
};
}

View File

@@ -1,19 +1,29 @@
#include <iostream>
#include <tins/tins.h>
#include <thread>
#include "map/natmap.h"
#include "natmap.h"
#include "PduSniffer.h"
#include "PduSender.h"
#include <json/json.h>
#include <json/value.h>
#include <fstream>
template<typename Container>
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<otonat::PduSniffer* > snifferList;
std::vector<std::thread * > 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;
}

View File

@@ -1,45 +0,0 @@
#include <iostream>
#include <tins/tins.h>
#include <thread>
#include "map/natmap.h"
#include "PduSniffer.h"
#include "PduSender.h"
#include <json/json.h>
#include <json/value.h>
#include <fstream>
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;
}

View File

@@ -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<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;
}
}

View File

@@ -18,8 +18,10 @@ namespace otonat {
typedef std::queue<const Tins::PDU *> PduQueue;
typedef std::pair<Tins::IPv4Address, Tins::IPv4Address> IPv4AddressEntry;
typedef std::map<Tins::IPv4Address, Tins::IPv4Address> IpAdressMap;
typedef unsigned short int Checksum;
typedef std::list<Checksum> ChecksumList;
typedef Tins::HWAddress<6> MacAddress;
typedef unsigned int NetworkInterfaceId;
typedef std::map<MacAddress, NetworkInterfaceId> SrcMacAdressNicIdMap;
typedef std::pair<MacAddress, NetworkInterfaceId> SrcMacAdressNicIdMapEntry;
NatMap() {
@@ -41,7 +43,7 @@ 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);
@@ -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;
};
}