From 614f02146a6b608336bee33d30a66be8131564c9 Mon Sep 17 00:00:00 2001 From: stubbfel Date: Fri, 21 Aug 2015 00:12:43 +0200 Subject: [PATCH] extends test and fix translation errors --- src/map/natmap.cpp | 63 ++++++++++++++++++------- src/map/natmap.h | 7 +-- tests/nattest.cpp | 115 ++++++++++++++++++++++++++++++++++++++++----- tests/nattest.h | 15 ++++-- 4 files changed, 164 insertions(+), 36 deletions(-) diff --git a/src/map/natmap.cpp b/src/map/natmap.cpp index e46c267..6a6308c 100644 --- a/src/map/natmap.cpp +++ b/src/map/natmap.cpp @@ -13,8 +13,7 @@ namespace otonat { //dtor } - NatMap::NatMap(const NatMap& other) : interfaces(other.interfaces) { - operator=(other); + 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::operator=(const NatMap& rhs) { @@ -48,32 +47,49 @@ namespace otonat { Tins::ARP * arp = pduCopy->find_pdu(); if (arp != 0) { - handleArp(arp); + if (handleArp(arp)) { + outgoingPduQueue.push(pduCopy); + } return; } Tins::IP * ip = pduCopy->find_pdu(); if (ip != 0) { - handleIp(ip); + if (handleIp(ip)) { + outgoingPduQueue.push(pduCopy); + } } } - void NatMap::handleIp(Tins::IP * ip) { - IpAdressMap::iterator transIpIter = transMap.find(ip->dst_addr()); + bool NatMap::handleIp(Tins::IP * ip) { + + if (isForMeOrFromMeIp(ip)) { + return false; + } + + const Tins::IPv4Address originDstIp = ip->dst_addr(); + IpAdressMap::iterator transIpIter = transMap.find(originDstIp); if (transIpIter != transMap.end()) { // handle know traslation ip - TranslateIpPacket(ip, transIpIter->second); + 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 { - // Determine Traslation Ip + return false; } } void NatMap::TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transIp) { - // copy ip packet, for modifaktion - Tins::IP * modifyIp = ip->clone(); // set translated dst address - modifyIp->dst_addr(transIp); + ip->dst_addr(transIp); // translate src adress const Tins::IPv4Address & originSrc = ip->src_addr(); @@ -83,14 +99,13 @@ namespace otonat { // set translated src address transSrcAttr = transIpIter->second; } else { - transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, interfaces); + transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transIp, interfaces); } - modifyIp->src_addr(transSrcAttr); - outgoingPduQueue.push(modifyIp); + ip->src_addr(transSrcAttr); } - Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, NetworkInterfaceList & interfaceList) { + Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NetworkInterfaceList & interfaceList) { // calc translated ip address for first up and not same interfaces for (const Tins::NetworkInterface & interface : interfaceList) { // insert or update translated ip address @@ -100,7 +115,7 @@ namespace otonat { } Tins::IPv4Range range = calcIpRange(interfaceInfo); //networkInterfaceIpRangeMap[interfaceInfo.ip_addr]; - if (range.contains(originIp)) { + if (!range.contains(transIp)) { continue; } @@ -128,7 +143,19 @@ namespace otonat { return transAddr; } - void NatMap::handleArp(Tins::ARP * /*arp*/) { - return; + bool NatMap::handleArp(Tins::ARP * /*arp*/) { + return false; + } + + bool NatMap::isForMeOrFromMeIp(const Tins::IP * ip) { + 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; + if (srcAddr == interfaceAddr || dstAddr == interfaceAddr) { + return true; + } + } + return false; } } diff --git a/src/map/natmap.h b/src/map/natmap.h index 7b0a1a6..5e4f32a 100644 --- a/src/map/natmap.h +++ b/src/map/natmap.h @@ -35,12 +35,13 @@ public: protected: private: - void handleIp(Tins::IP * ip); - void handleArp(Tins::ARP * arp); + 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, NetworkInterfaceList & interfaceList); + 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); }; } diff --git a/tests/nattest.cpp b/tests/nattest.cpp index 79285a0..59a9ba6 100644 --- a/tests/nattest.cpp +++ b/tests/nattest.cpp @@ -11,6 +11,12 @@ CPPUNIT_TEST_SUITE_REGISTRATION(nattest); nattest::nattest() { + Tins::NetworkInterface net1("vboxnet0"); + Tins::NetworkInterface net2("vboxnet1"); + otonat::NatMap::NetworkInterfaceList list; + list.push_back(net1); + list.push_back(net2); + natMap = otonat::NatMap(list); } nattest::~nattest() { @@ -65,26 +71,113 @@ void nattest::testIpCalcEth2() { } void nattest::testTranslateIp() { - Tins::EthernetII eth = Tins::EthernetII("00:00:00:00:00:01" ,"00:00:00:00:00:02") / Tins::IP("172.27.0.20", "172.16.3.55") / Tins::TCP(); - Tins::EthernetII eth2 = Tins::EthernetII("00:00:00:00:00:01" ,"00:00:00:00:00:03") / Tins::IP("172.27.0.20", "172.17.3.55") / Tins::TCP(); - Tins::NetworkInterface net1("lo:0"); - Tins::NetworkInterface net2("lo:1"); - otonat::NatMap::NetworkInterfaceList list; - list.push_back(net1); - list.push_back(net2); - otonat::NatMap natMap = otonat::NatMap(list); + Tins::EthernetII eth = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:02") / Tins::IP("172.27.0.20", "172.16.3.55") / Tins::TCP(); + Tins::EthernetII ethAck = Tins::EthernetII("00:00:00:00:00:02", "00:00:00:00:00:01") / Tins::IP("10.0.3.55", "10.0.0.20") / Tins::TCP(); + Tins::EthernetII eth2 = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:03") / Tins::IP("172.27.0.20", "172.17.3.55") / Tins::TCP(); + Tins::EthernetII eth2Ack = Tins::EthernetII("00:00:00:00:00:03", "00:00:00:00:00:01") / Tins::IP("10.0.3.55", "10.0.0.20") / Tins::TCP(); + Tins::EthernetII eth3 = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:04") / Tins::IP("172.27.0.20", "172.18.1.40") / Tins::TCP(); + Tins::EthernetII eth3Ack = Tins::EthernetII("00:00:00:00:00:04", "00:00:00:00:00:01") / Tins::IP("10.0.1.40", "10.0.0.20") / Tins::TCP(); + natMap.handlePdu(ð); CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + natMap.transMap.insert(otonat::NatMap::IPv4AddressEntry(Tins::IPv4Address("172.27.0.20"), Tins::IPv4Address("10.0.0.20"))); + natMap.handlePdu(ð); - CPPUNIT_ASSERT(natMap.outgoingPduQueue.size()== 1); - const Tins::PDU * result = natMap.outgoingPduQueue.front(); - std::cout << "outgoingip: " << result->rfind_pdu().src_addr() << std::endl; + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result = natMap.outgoingPduQueue.front(); + checkEth(result->rfind_pdu(), "00:00:00:00:00:01", "00:00:00:00:00:02", "10.0.0.20", "10.0.3.55"); natMap.outgoingPduQueue.pop(); CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ðAck); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * resultAck = natMap.outgoingPduQueue.front(); + checkEth(resultAck->rfind_pdu(), "00:00:00:00:00:02", "00:00:00:00:00:01", "172.16.3.55", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ð2); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result2 = natMap.outgoingPduQueue.front(); + checkEth(result2->rfind_pdu(), "00:00:00:00:00:01", "00:00:00:00:00:03", "10.0.0.20", "10.0.3.55"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ð2Ack); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result2Ack = natMap.outgoingPduQueue.front(); + checkEth(result2Ack->rfind_pdu(), "00:00:00:00:00:03", "00:00:00:00:00:01", "172.17.3.55", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ð3); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result3 = natMap.outgoingPduQueue.front(); + checkEth(result3->rfind_pdu(), "00:00:00:00:00:01", "00:00:00:00:00:04", "10.0.0.20", "10.0.1.40"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ð3Ack); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result3Ack = natMap.outgoingPduQueue.front(); + checkEth(result3Ack->rfind_pdu(), "00:00:00:00:00:04", "00:00:00:00:00:01", "172.18.4.40", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); +} + +void nattest::testForMeFromMe() { + Tins::EthernetII forMe = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:03") / Tins::IP("172.16.0.1", "172.17.3.55") / Tins::TCP(); + Tins::EthernetII FromMe = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:03") / Tins::IP("172.27.0.20", "172.16.0.1") / Tins::TCP(); + natMap.transMap.insert(otonat::NatMap::IPv4AddressEntry(Tins::IPv4Address("172.27.0.20"), Tins::IPv4Address("10.0.0.20"))); + + natMap.handlePdu(&forMe); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(&FromMe); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); } void nattest::testNatInterfaces() { CPPUNIT_ASSERT(!natMap.interfaces.empty()); } +void nattest::printIp(const Tins::IP & ip) { + std::cout << std::endl << "### Ip-Packet ###" << std::endl; + std::cout << "ip_dst: " << ip.dst_addr() << std::endl; + std::cout << "ip_src: " << ip.src_addr() << std::endl; + std::cout << "#################" << std::endl; +} + +void nattest::printEth(const Tins::EthernetII & eth) { + std::cout << std::endl << "+++ Ethernet-Frame +++" << std::endl; + std::cout << "frame_dst: " << eth.dst_addr() << std::endl; + std::cout << "frame_src: " << eth.src_addr(); + printIp(eth.rfind_pdu()); + std::cout << "++++++++++++++++++++++" << std::endl; +} + +void nattest::checkAndPrintIp(const Tins::IP & ip, const Tins::IPv4Address & targetSrcIp, const Tins::IPv4Address & targetDstIp) { + printIp(ip); + checkIp(ip, targetDstIp, targetSrcIp); +} + +void nattest::checkAndPrintEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & targetDstMac, const Tins::HWAddress<6> & targetSrcMac, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp) { + printEth(eth); + checkEth(eth, targetDstMac, targetSrcMac, targetDstIp, targetSrcIp); +} + +void nattest::checkIp(const Tins::IP & ip, const Tins::IPv4Address & targetSrcIp, const Tins::IPv4Address & targetDstIp) { + const Tins::IPv4Address & packetSrcIp = ip.src_addr(); + const Tins::IPv4Address & packetDstIp = ip.dst_addr(); + CPPUNIT_ASSERT_EQUAL(targetSrcIp, packetSrcIp); + CPPUNIT_ASSERT_EQUAL(targetDstIp, packetDstIp); +} + +void nattest::checkEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & targetDstMac, const Tins::HWAddress<6> & targetSrcMac, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp) { + const Tins::HWAddress<6> & frameSrcMac = eth.src_addr(); + const Tins::HWAddress<6> & frameDstMac = eth.dst_addr(); + CPPUNIT_ASSERT_EQUAL(targetSrcMac, frameSrcMac); + CPPUNIT_ASSERT_EQUAL(targetDstMac, frameDstMac); +} + diff --git a/tests/nattest.h b/tests/nattest.h index 9064f44..3e5dfc8 100644 --- a/tests/nattest.h +++ b/tests/nattest.h @@ -15,13 +15,12 @@ class nattest : public CPPUNIT_NS::TestFixture { CPPUNIT_TEST_SUITE(nattest); - + CPPUNIT_TEST(testTranslateIp); CPPUNIT_TEST(testNatInterfaces); CPPUNIT_TEST(testIpCalcEth0); CPPUNIT_TEST(testIpCalcEth1); CPPUNIT_TEST(testIpCalcEth2); - CPPUNIT_TEST(testTranslateIp); - + CPPUNIT_TEST(testForMeFromMe); CPPUNIT_TEST_SUITE_END(); public: @@ -31,7 +30,7 @@ public: void tearDown(); private: - otonat::NatMap natMap = otonat::NatMap(); + otonat::NatMap natMap; Tins::IPv4Address deviceIpEth0 = Tins::IPv4Address("10.0.3.40"); Tins::IPv4Address deviceIpEth1 = Tins::IPv4Address("192.168.23.42"); Tins::IPv4Address deviceIpEth2 = Tins::IPv4Address("172.27.123.4"); @@ -64,6 +63,14 @@ private: void testIpCalcEth1(); void testIpCalcEth2(); void testTranslateIp(); + void testForMeFromMe(); + + void printIp(const Tins::IP & ip); + void printEth(const Tins::EthernetII & eth); + void checkAndPrintIp(const Tins::IP & ip, const Tins::IPv4Address & targetSrcIp, const Tins::IPv4Address & targetDstIp); + void checkAndPrintEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & targetDstMac, const Tins::HWAddress<6> & targetSrcMac, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp); + void checkIp(const Tins::IP & ip, const Tins::IPv4Address & targetSrcIp, const Tins::IPv4Address & targetDstIp); + void checkEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & targetDstMac, const Tins::HWAddress<6> & targetSrcMac, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp); }; #endif /* NATTEST_H */