add natrange

This commit is contained in:
stubbfel
2015-08-22 01:00:52 +02:00
parent 614f02146a
commit 411dcbcc12
11 changed files with 305 additions and 84 deletions

View File

@@ -2,6 +2,7 @@
#include <tins/tins.h>
#include <thread>
using namespace std;
using namespace Tins;

81
src/map/NatRange.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include "NatRange.h"
namespace otonat {
NatRange::NatRange(Tins::NetworkInterface interface, Tins::IPv4Address rangeIpAddr, Tins::IPv4Address netmask) : interface(interface), rangeIpAddr(rangeIpAddr), rangeNetmask(netmask) {
}
NatRange& NatRange::operator=(const NatRange& right) {
// Check for self-assignment!
if (this == &right) // Same object?
return *this; // Yes, so skip assignment, and just return *this.
interface = right.interface;
rangeIpAddr = right.rangeIpAddr;
rangeNetmask = right.rangeNetmask;
return *this;
}
NatRange::NatRange(const NatRange& other) : interface(other.interface), rangeIpAddr(other.rangeIpAddr), rangeNetmask(other.rangeNetmask) {
}
NatRange::~NatRange() {
}
Tins::IPv4Range NatRange::calcIpRange(const Tins::IPv4Address &ip, const Tins::IPv4Address & netmask) {
return Tins::IPv4Range::from_mask(ip, netmask);
}
Tins::IPv4Range NatRange::calcIpRange(const Tins::NetworkInterface::Info & interfaceInfo) {
return calcIpRange(interfaceInfo.ip_addr, interfaceInfo.netmask);
}
Tins::IPv4Range NatRange::calcIpRange(const Tins::NetworkInterface & interface) {
return calcIpRange(interface.info());
}
Tins::IPv4Range NatRange::calcIpRange(const NatRange & natRange) {
return calcIpRange(natRange.rangeIpAddr, natRange.rangeNetmask);
}
Tins::IPv4Range NatRange::calcIpRange(const NatRange& natRange, const bool usedInterfaceIpSetting) {
if (usedInterfaceIpSetting) {
return calcIpRange(natRange.interface);
}
return calcIpRange(natRange);
}
Tins::IPv4Range NatRange::calcIpRange(const bool usedInterfaceIpSetting) const {
return calcIpRange(*this, usedInterfaceIpSetting);
}
Tins::IPv4Address NatRange::mapIPv4Address(const Tins::IPv4Address& originIp, const Tins::NetworkInterface& interface) {
return mapIPv4Address(originIp, interface.info());
}
Tins::IPv4Address NatRange::mapIPv4Address(const Tins::IPv4Address & originIp, const Tins::NetworkInterface::Info & interfaceInfo) {
return mapIPv4Address(originIp, interfaceInfo.ip_addr, interfaceInfo.netmask);
}
Tins::IPv4Address NatRange::mapIPv4Address(const Tins::IPv4Address& originIp, const NatRange& natRange) {
return mapIPv4Address(originIp, natRange.rangeIpAddr, natRange.rangeNetmask);
}
Tins::IPv4Address NatRange::mapIPv4Address(const Tins::IPv4Address& originIp, const Tins::IPv4Address& netIp, const Tins::IPv4Address& netmask) {
const uint32_t networkStartIp = netIp & netmask;
const uint32_t resultIp = (originIp & ~netmask) | networkStartIp;
return Tins::IPv4Address(resultIp);
}
Tins::IPv4Address NatRange::mapIPv4Address(const Tins::IPv4Address& originIp, const NatRange& natRange, const bool usedInterfaceIpSetting) {
if (usedInterfaceIpSetting) {
return mapIPv4Address(originIp, natRange.interface);
}
return mapIPv4Address(originIp, natRange);
}
Tins::IPv4Address NatRange::mapIPv4Addres(const Tins::IPv4Address& originIp, const bool usedInterfaceIpSetting) const {
return mapIPv4Address(originIp, *this, usedInterfaceIpSetting);
}
}

36
src/map/NatRange.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef NATRANGE_H
#define NATRANGE_H
#include <tins/tins.h>
namespace otonat {
class NatRange {
public:
NatRange(Tins::NetworkInterface interface, Tins::IPv4Address rangeIpAddr, Tins::IPv4Address netmask);
NatRange(const NatRange& orig);
NatRange& operator=(const NatRange& right);
virtual ~NatRange();
Tins::NetworkInterface interface;
Tins::IPv4Address rangeIpAddr;
Tins::IPv4Address rangeNetmask;
Tins::IPv4Range calcIpRange(const bool usedInterfaceIpSetting) const;
static Tins::IPv4Range calcIpRange(const Tins::IPv4Address &ip, const Tins::IPv4Address & netmask);
static Tins::IPv4Range calcIpRange(const Tins::NetworkInterface::Info & interfaceInfo);
static Tins::IPv4Range calcIpRange(const Tins::NetworkInterface & interface);
static Tins::IPv4Range calcIpRange(const NatRange & natRange);
static Tins::IPv4Range calcIpRange(const NatRange & natRange, const bool usedInterfaceIpSetting);
Tins::IPv4Address mapIPv4Addres(const Tins::IPv4Address & originIp, const bool usedInterfaceIpSetting) const;
static Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & originIp, const Tins::IPv4Address & netIp, const Tins::IPv4Address & netmask);
static Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & originIp, const Tins::NetworkInterface::Info & interfaceInfo);
static Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & originIp, const Tins::NetworkInterface & interface);
static Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & originIp, const NatRange & natRange);
static Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & originIp, const NatRange & natRange, const bool usedInterfaceIpSetting);
private:
};
}
#endif /* NATRANGE_H */

View File

@@ -2,24 +2,20 @@
namespace otonat {
NatMap::NatMap() : NatMap(Tins::NetworkInterface::all()) {
//ctor
}
NatMap::NatMap(NetworkInterfaceList interfaceList) : interfaces(interfaceList) {
NatMap::NatMap(NatRangeList rangeList) : ranges(rangeList) {
}
NatMap::~NatMap() {
//dtor
}
NatMap::NatMap(const NatMap& other) : interfaces(other.interfaces), arpMap(other.arpMap), transMap(other.transMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue), zeroIp(other.zeroIp) {
NatMap::NatMap(const NatMap& other) : ranges(other.ranges), arpMap(other.arpMap), transMap(other.transMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue), zeroIp(other.zeroIp) {
}
NatMap& NatMap::operator=(const NatMap& rhs) {
if (this == &rhs) return *this; // handle self assignment
interfaces = rhs.interfaces;
ranges = rhs.ranges;
arpMap = rhs.arpMap;
transMap = rhs.transMap;
incommingPduQueue = rhs.incommingPduQueue;
@@ -27,18 +23,6 @@ namespace otonat {
return *this;
}
const Tins::IPv4Address NatMap::mapIPv4Address(const Tins::IPv4Address & ip, const Tins::NetworkInterface::Info & interfaceInfo) {
const uint32_t & netmask = interfaceInfo.netmask;
const uint32_t & interfaceIp = interfaceInfo.ip_addr;
const uint32_t networkStartIp = interfaceIp & netmask;
const uint32_t resultIp = (ip & ~netmask) | networkStartIp;
return Tins::IPv4Address(resultIp);
}
const Tins::IPv4Range NatMap::calcIpRange(const Tins::NetworkInterface::Info & interfaceInfo) {
return Tins::IPv4Range::from_mask(interfaceInfo.ip_addr, interfaceInfo.netmask);
}
void NatMap::handlePdu(const Tins::PDU * pdu) {
Tins::PDU * pduCopy = pdu->clone();
if (pdu == NULL) {
@@ -67,7 +51,11 @@ namespace otonat {
return false;
}
const Tins::IPv4Address originDstIp = ip->dst_addr();
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
@@ -79,7 +67,7 @@ namespace otonat {
} else if (transDstIpIter->second != originDstIp) {
transMap[transDstIp] = originDstIp;
}
return true;
} else {
return false;
@@ -93,41 +81,42 @@ namespace otonat {
// 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, transIp, interfaces);
transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transIp, ranges);
}
ip->src_addr(transSrcAttr);
}
Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NetworkInterfaceList & interfaceList) {
Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NatRangeList & rangeList) {
// calc translated ip address for first up and not same interfaces
for (const Tins::NetworkInterface & interface : interfaceList) {
for (NatRange & range : rangeList) {
// insert or update translated ip address
const Tins::NetworkInterface::Info & interfaceInfo = interface.info();
const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info();
if (!interfaceInfo.is_up) {
continue;
}
Tins::IPv4Range range = calcIpRange(interfaceInfo); //networkInterfaceIpRangeMap[interfaceInfo.ip_addr];
if (!range.contains(transIp)) {
Tins::IPv4Range ipRange = range.calcIpRange(true);
if (!ipRange.contains(transIp)) {
continue;
}
return InsertOrUdpateTranslateIpAddress(originIp, interfaceInfo);
return InsertOrUdpateTranslateIpAddress(originIp, range);
}
return zeroIp;
}
Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::NetworkInterface::Info & interfaceInfo) {
Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const NatRange & range) {
// translated ip address
Tins::IPv4Address transAddr = mapIPv4Address(originIp, interfaceInfo);
Tins::IPv4Address transAddr = range.mapIPv4Addres(originIp, false);
// insert forward translation
transMap.insert(IPv4AddressEntry(originIp, transAddr));
@@ -147,15 +136,33 @@ namespace otonat {
return false;
}
bool NatMap::isForMeOrFromMeIp(const Tins::IP * ip) {
bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) {
return isForMeOrFromMeIp(ip, ranges);
}
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 (Tins::NetworkInterface interface : interfaces) {
const Tins::IPv4Address & interfaceAddr = interface.info().ip_addr;
for (NatRange range : rangeList) {
const Tins::IPv4Address & interfaceAddr = range.interface.info().ip_addr;
if (srcAddr == interfaceAddr || dstAddr == interfaceAddr) {
return true;
}
}
return false;
}
bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) {
return isIpInMyRanges(ipAddr, ranges);
}
bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList) {
for (NatRange range : rangeList) {
if (range.calcIpRange(true).contains(ipAddr)) {
return true;
}
}
return false;
}
}

View File

@@ -5,44 +5,45 @@
#include <map>
#include <queue>
#include <tins/tins.h>
#include "NatRange.h"
namespace otonat {
namespace otonat
{
class NatMap
{
public:
typedef std::vector<Tins::NetworkInterface> NetworkInterfaceList;
typedef std::queue<const Tins::PDU *> PduQueue;
typedef std::pair<Tins::IPv4Address,Tins::IPv4Address> IPv4AddressEntry;
typedef std::map<Tins::IPv4Address, Tins::HWAddress<6>> IpAdressMacMap;
typedef std::map<Tins::IPv4Address, Tins::IPv4Address> IpAdressMap;
class NatMap {
public:
typedef std::vector<NatRange> NatRangeList;
typedef std::queue<const Tins::PDU *> PduQueue;
typedef std::pair<Tins::IPv4Address, Tins::IPv4Address> IPv4AddressEntry;
typedef std::map<Tins::IPv4Address, Tins::HWAddress < 6 >> IpAdressMacMap;
typedef std::map<Tins::IPv4Address, Tins::IPv4Address> IpAdressMap;
NatMap() {
}
NatMap();
NatMap(NetworkInterfaceList interfaceList);
virtual ~NatMap();
NatMap(const NatMap& other);
NatMap& operator=(const NatMap& other);
NetworkInterfaceList interfaces;
IpAdressMacMap arpMap;
IpAdressMap transMap;
PduQueue incommingPduQueue;
PduQueue outgoingPduQueue;
void handlePdu(const Tins::PDU * pdu);
static const Tins::IPv4Address mapIPv4Address(const Tins::IPv4Address & ip, const Tins::NetworkInterface::Info & interfaceInfo);
static const Tins::IPv4Range calcIpRange(const Tins::NetworkInterface::Info & interfaceInfo);
NatMap(NatRangeList rangeList);
virtual ~NatMap();
NatMap(const NatMap& other);
NatMap& operator=(const NatMap& other);
NatRangeList ranges;
IpAdressMacMap arpMap;
IpAdressMap transMap;
PduQueue incommingPduQueue;
PduQueue outgoingPduQueue;
void handlePdu(const Tins::PDU * pdu);
protected:
protected:
private:
bool handleIp(Tins::IP * ip);
bool handleArp(Tins::ARP * arp);
Tins::IPv4Address InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::NetworkInterface::Info & interfaceInfo);
Tins::IPv4Address InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NetworkInterfaceList & interfaceList);
void TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transIp);
Tins::IPv4Address zeroIp;
bool isForMeOrFromMeIp(const Tins::IP * ip);
};
private:
bool handleIp(Tins::IP * ip);
bool handleArp(Tins::ARP * arp);
Tins::IPv4Address InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const NatRange & range);
Tins::IPv4Address InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NatRangeList & rangeList);
void TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transIp);
Tins::IPv4Address zeroIp;
bool isForMeOrFromMeIp(const Tins::IP * ip);
static bool isForMeOrFromMeIp(const Tins::IP * ip, const NatRangeList & rangeList);
bool isIpInMyRanges(const Tins::IPv4Address & ipAddr);
static bool isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList);
};
}