From 5476f0ea563b9812897497e9952f64bc0d64c0fc Mon Sep 17 00:00:00 2001 From: stubbfel Date: Wed, 2 Sep 2015 23:32:23 +0200 Subject: [PATCH] add arp tests and fix insert trnaslate --- src/map/natmap.cpp | 165 +++++++++++++++++++++++++-------------- src/map/natmap.h | 18 ++--- tests/nattest.cpp | 188 ++++++++++++++++++++++++++++++++++++++++++++- tests/nattest.h | 7 ++ 4 files changed, 309 insertions(+), 69 deletions(-) diff --git a/src/map/natmap.cpp b/src/map/natmap.cpp index 57851e4..abd9a0b 100644 --- a/src/map/natmap.cpp +++ b/src/map/natmap.cpp @@ -6,17 +6,26 @@ namespace otonat { } NatMap::~NatMap() { - //dtor + ranges.clear(); + transMap.clear(); + reqIpMap.clear(); + while (!incommingPduQueue.empty()){ + incommingPduQueue.pop(); + } + + while (!outgoingPduQueue.empty()){ + outgoingPduQueue.pop(); + } + } - NatMap::NatMap(const NatMap& other) : ranges(other.ranges), arpMap(other.arpMap), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue), zeroIp(other.zeroIp) { + NatMap::NatMap(const NatMap& other) : ranges(other.ranges), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue), zeroIp(other.zeroIp) { } NatMap& NatMap::operator=(const NatMap& rhs) { if (this == &rhs) return *this; // handle self assignment ranges = rhs.ranges; - arpMap = rhs.arpMap; transMap = rhs.transMap; incommingPduQueue = rhs.incommingPduQueue; outgoingPduQueue = rhs.outgoingPduQueue; @@ -52,7 +61,7 @@ namespace otonat { return false; } - const Tins::IPv4Address & originDstIp = ip->dst_addr(); + const Tins::IPv4Address originDstIp = ip->dst_addr(); if (!isIpInMyRanges(originDstIp)) { return false; } @@ -81,13 +90,13 @@ namespace otonat { } } - void NatMap::TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transIp) { + void NatMap::TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transDstIp) { // set translated dst address - ip->dst_addr(transIp); + ip->dst_addr(transDstIp); // translate src adress - const Tins::IPv4Address & originSrc = ip->src_addr(); + const Tins::IPv4Address originSrc = ip->src_addr(); IpAdressMap::const_iterator transIpIter = transMap.find(originSrc); Tins::IPv4Address transSrcAttr; @@ -95,13 +104,13 @@ namespace otonat { // set translated src address transSrcAttr = transIpIter->second; } else { - transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transIp, ranges); + transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transDstIp, ranges); } ip->src_addr(transSrcAttr); } - Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp, NatRangeList & rangeList) { + 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 @@ -110,8 +119,8 @@ namespace otonat { continue; } - Tins::IPv4Range ipRange = range.calcIpRange(true); - if (!ipRange.contains(transIp)) { + const Tins::IPv4Range ipRange = range.calcIpRange(true); + if (!ipRange.contains(otherTransSameRangeIp)) { continue; } @@ -123,28 +132,37 @@ namespace otonat { Tins::IPv4Address NatMap::InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const NatRange & range) { // translated ip address - Tins::IPv4Address transAddr = range.mapIPv4Addres(originIp, false); + const Tins::IPv4Address transAddr = range.mapIPv4Addres(originIp, false); // insert forward translation - transMap.insert(IPv4AddressEntry(originIp, transAddr)); + InsertOrUdpateTranslateIpAddress(originIp, transAddr); // insert or update backward translation - IpAdressMap::const_iterator transIpIter = transMap.find(transAddr); - if (transIpIter != transMap.end()) { - transMap[transAddr] = originIp; - } else { - transMap.insert(IPv4AddressEntry(transAddr, originIp)); - } + 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); @@ -155,11 +173,11 @@ namespace otonat { } } - bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) { + bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) const { return isForMeOrFromMeIp(ip, ranges); } - bool NatMap::isForMeOrFromMeArp(const Tins::ARP * arp) { + bool NatMap::isForMeOrFromMeArp(const Tins::ARP * arp) const { Tins::IP fakeIp(arp->target_ip_addr(), arp->sender_ip_addr()); return isForMeOrFromMeIp(&fakeIp); } @@ -176,7 +194,7 @@ namespace otonat { return false; } - bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) { + bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) const { return isIpInMyRanges(ipAddr, ranges); } @@ -191,71 +209,104 @@ namespace otonat { } bool NatMap::handleArpReq(Tins::ARP* arp) { - Tins::IPv4Address targetIp = arp->target_ip_addr(); + const Tins::IPv4Address targetIp = arp->target_ip_addr(); IpAdressMap::const_iterator transTargetIpIter = this->transMap.find(targetIp); if (transTargetIpIter == transMap.end()) { SendTranslatedArpRequest(arp); return false; } - Tins::IPv4Address transTargetIp = transTargetIpIter->second; + 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); return false; } - + return handleArpAndTranslateSenderIp(arp); } bool NatMap::handleArpReply(Tins::ARP* arp) { - return false; + const Tins::IPv4Address targetIp = arp->target_ip_addr(); + const Tins::IPv4Address transTargetIp = TranslateArpIp(targetIp); + if(transTargetIp == this->zeroIp){ + return false; + } + + const Tins::IPv4Address senderIp = arp->sender_ip_addr(); + const Tins::IPv4Address transSenderIp = TranslateArpIp(senderIp); + if(transSenderIp == this->zeroIp){ + return false; + } + + arp->target_ip_addr(transTargetIp); + arp->sender_ip_addr(transSenderIp); + return true; } - - bool NatMap::handleArpAndTranslateSenderIp(Tins::ARP* arp) { - for (NatRange & range : this->ranges) { - const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); - if (!interfaceInfo.is_up) { - continue; - } - Tins::IPv4Range ipRange = range.calcIpRange(true); - if (!ipRange.contains(arp->target_ip_addr())) { - continue; - } - - Tins::IPv4Address senderIp = arp->sender_ip_addr(); - 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; + 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 this->zeroIp; } + + transArpIp = transReqArpIpIter->second; + this->InsertOrUdpateTranslateIpAddress(arpIp, transArpIp); + this->InsertOrUdpateTranslateIpAddress(transArpIp, arpIp); + this->reqIpMap.erase(transReqArpIpIter); + return transArpIp; + } - return false; + return transArpIpIter->second; } - void NatMap::SendTranslatedArpRequest(const Tins::ARP * arp) { - Tins::IPv4Address targetIp = arp->target_ip_addr(); + bool NatMap::handleArpAndTranslateSenderIp(Tins::ARP* arp) { for (NatRange & range : this->ranges) { const Tins::NetworkInterface::Info & interfaceInfo = range.interface.info(); if (!interfaceInfo.is_up) { continue; } - Tins::IPv4Range ipRange = range.calcIpRange(true); + 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 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; } - Tins::IPv4Address senderIp = arp->sender_ip_addr(); - Tins::IPv4Address transSenderIp = range.mapIPv4Addres(senderIp, true); - Tins::IPv4Address transTargetIp = range.mapIPv4Addres(targetIp, true); + 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)); @@ -266,8 +317,8 @@ namespace otonat { this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); } - Tins::EthernetII transArp = Tins::ARP::make_arp_request(transTargetIp, transSenderIp, arp->sender_hw_addr()); - outgoingPduQueue.push(transArp.clone()); + const Tins::EthernetII transArp = Tins::ARP::make_arp_request(transTargetIp, transSenderIp, arp->sender_hw_addr()); + this->outgoingPduQueue.push(transArp.clone()); } } } diff --git a/src/map/natmap.h b/src/map/natmap.h index 36855e4..43932fc 100644 --- a/src/map/natmap.h +++ b/src/map/natmap.h @@ -13,7 +13,6 @@ namespace otonat { typedef std::vector NatRangeList; typedef std::queue PduQueue; typedef std::pair IPv4AddressEntry; - typedef std::map> IpAdressMacMap; typedef std::map IpAdressMap; NatMap() { @@ -24,7 +23,6 @@ namespace otonat { NatMap(const NatMap& other); NatMap& operator=(const NatMap& other); NatRangeList ranges; - IpAdressMacMap arpMap; IpAdressMap transMap; IpAdressMap reqIpMap; PduQueue incommingPduQueue; @@ -38,15 +36,17 @@ namespace otonat { bool handleArp(Tins::ARP * arp); bool handleArpReq(Tins::ARP * arp); bool handleArpReply(Tins::ARP * arp); - bool handleArpAndTranslateSenderIp(Tins::ARP* arp); + bool handleArpAndTranslateSenderIp(Tins::ARP * arp); + void InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & transIp); 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); - bool isForMeOrFromMeArp(const Tins::ARP * arp); + Tins::IPv4Address InsertOrUdpateTranslateIpAddress(const Tins::IPv4Address & originIp, const Tins::IPv4Address & otherTransSameRangeIp, NatRangeList & rangeList); + void TranslateIpPacket(Tins::IP * ip, const Tins::IPv4Address & transDstIp); + const Tins::IPv4Address TranslateArpIp(const Tins::IPv4Address & arpIp); + const Tins::IPv4Address zeroIp; + bool isForMeOrFromMeIp(const Tins::IP * ip) const; + bool isForMeOrFromMeArp(const Tins::ARP * arp) const; static bool isForMeOrFromMeIp(const Tins::IP * ip, const NatRangeList & rangeList); - bool isIpInMyRanges(const Tins::IPv4Address & ipAddr); + bool isIpInMyRanges(const Tins::IPv4Address & ipAddr) const; static bool isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList); void SendTranslatedArpRequest(const Tins::ARP * arp); }; diff --git a/tests/nattest.cpp b/tests/nattest.cpp index 4178469..6e6429b 100644 --- a/tests/nattest.cpp +++ b/tests/nattest.cpp @@ -73,7 +73,138 @@ void nattest::testIpCalcEth2() { CPPUNIT_ASSERT_EQUAL(expetedIp, resultIp); } +void nattest::testTranslateArpIp(){ + natMap.reqIpMap.clear(); + natMap.transMap.clear(); + Tins::EthernetII arp1 = Tins::ARP::make_arp_request("172.17.0.20", "172.16.3.55", "00:00:00:00:00:02"); + Tins::EthernetII arp2 = Tins::ARP::make_arp_request("172.27.0.20", "172.16.3.55", "00:00:00:00:00:02"); + Tins::EthernetII arp3 = Tins::ARP::make_arp_reply("10.0.3.55", "10.0.0.20", "00:00:00:00:00:02", "00:00:00:00:00:01"); + Tins::EthernetII arp4 = Tins::ARP::make_arp_reply("10.128.3.55", "10.0.0.20", "00:00:00:00:00:03", "00:00:00:00:00:01"); + Tins::EthernetII ethW = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:02") / Tins::IP("172.17.0.20", "172.16.3.55") / Tins::TCP(); + 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(); + Tins::EthernetII eth4 = Tins::EthernetII("00:00:00:00:00:02", "00:00:00:00:00:05") / Tins::IP("10.0.3.55", "10.0.1.41") / Tins::TCP(); + Tins::EthernetII eth4Ack = Tins::EthernetII("00:00:00:00:00:05", "00:00:00:00:00:02") / Tins::IP("172.27.1.41", "172.17.3.55") / Tins::TCP(); + + natMap.handlePdu(arp1.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(arp2.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * resultArp1 = natMap.outgoingPduQueue.front(); + checkArp(resultArp1->rfind_pdu(), Tins::ARP::REQUEST, "00:00:00:00:00:00", "00:00:00:00:00:02", "10.0.0.20", "10.0.3.55"); + natMap.outgoingPduQueue.pop(); + + natMap.handlePdu(arp3.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * resultArp2 = natMap.outgoingPduQueue.front(); + checkArp(resultArp2->rfind_pdu(), Tins::ARP::REPLY, "00:00:00:00:00:02", "00:00:00:00:00:01", "172.16.3.55", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + + natMap.handlePdu(arp4.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(ethW.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(eth.clone()); + 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(ethAck.clone()); + 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(eth2.clone()); + 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(eth2Ack.clone()); + 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(eth3.clone()); + 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(eth3Ack.clone()); + 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.1.40", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(eth4.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result4 = natMap.outgoingPduQueue.front(); + checkEth(result4->rfind_pdu(), "00:00:00:00:00:02", "00:00:00:00:00:05", "172.17.3.55", "172.27.1.41"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(eth4Ack.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * result4Ack = natMap.outgoingPduQueue.front(); + checkEth(result4Ack->rfind_pdu(), "00:00:00:00:00:05", "00:00:00:00:00:02", "10.0.1.41", "10.0.3.55"); + natMap.outgoingPduQueue.pop(); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + CPPUNIT_ASSERT(natMap.transMap.size() == 9); + CPPUNIT_ASSERT(natMap.reqIpMap.empty()); + /*for (auto& entry : natMap.transMap){ + std::cout << std::endl << "ip_dst: " << entry.first << std::endl; + std::cout << "ip_src: " << entry.second << std::endl; + }*/ +} + +void nattest::testTranslateArp() { + natMap.reqIpMap.clear(); + natMap.transMap.clear(); + Tins::EthernetII arp1 = Tins::ARP::make_arp_request("172.17.0.20", "172.16.3.55", "00:00:00:00:00:02"); + Tins::EthernetII arp2 = Tins::ARP::make_arp_request("172.27.0.20", "172.16.3.55", "00:00:00:00:00:02"); + Tins::EthernetII arp3 = Tins::ARP::make_arp_reply("10.0.3.55", "10.0.0.20", "00:00:00:00:00:02", "00:00:00:00:00:01"); + Tins::EthernetII arp4 = Tins::ARP::make_arp_reply("10.128.3.55", "10.0.0.20", "00:00:00:00:00:03", "00:00:00:00:00:01"); + + natMap.handlePdu(arp1.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); + + natMap.handlePdu(arp2.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * resultArp1 = natMap.outgoingPduQueue.front(); + checkArp(resultArp1->rfind_pdu(), Tins::ARP::REQUEST, "00:00:00:00:00:00", "00:00:00:00:00:02", "10.0.0.20", "10.0.3.55"); + natMap.outgoingPduQueue.pop(); + + natMap.handlePdu(arp3.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); + const Tins::PDU * resultArp2 = natMap.outgoingPduQueue.front(); + checkArp(resultArp2->rfind_pdu(), Tins::ARP::REPLY, "00:00:00:00:00:02", "00:00:00:00:00:01", "172.16.3.55", "172.27.0.20"); + natMap.outgoingPduQueue.pop(); + + natMap.handlePdu(arp4.clone()); + CPPUNIT_ASSERT(natMap.outgoingPduQueue.empty()); +} + void nattest::testTranslateIp() { + natMap.reqIpMap.clear(); + natMap.transMap.clear(); Tins::EthernetII ethW = Tins::EthernetII("00:00:00:00:00:01", "00:00:00:00:00:02") / Tins::IP("172.17.0.20", "172.16.3.55") / Tins::TCP(); 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(); @@ -86,7 +217,9 @@ void nattest::testTranslateIp() { natMap.handlePdu(eth.clone()); CPPUNIT_ASSERT(natMap.outgoingPduQueue.size() == 1); - natMap.outgoingPduQueue.pop(); + const Tins::PDU * resultArp1 = natMap.outgoingPduQueue.front(); + checkArp(resultArp1->rfind_pdu(), Tins::ARP::REQUEST, "00:00:00:00:00:00", "00:00:00:00:00:02", "10.0.0.20", "10.0.3.55"); + natMap.outgoingPduQueue.pop(); natMap.transMap.insert(otonat::NatMap::IPv4AddressEntry(Tins::IPv4Address("172.27.0.20"), Tins::IPv4Address("10.0.0.20"))); @@ -177,10 +310,39 @@ 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()); + const Tins::IP * ip = eth.find_pdu(); + if (ip != nullptr) { + printIp(*ip); + } + + const Tins::ARP * arp = eth.find_pdu(); + if (arp != nullptr) { + printArp(*arp); + } else { + std::cout << std::endl; + } + std::cout << "++++++++++++++++++++++" << std::endl; } +void nattest::printArp(const Tins::ARP & arp) { + std::cout << std::endl << "@@@ ARP-Frame @@@" << std::endl; + switch (arp.opcode()) { + case Tins::ARP::REQUEST: + std::cout << "type: Request" << std::endl; + break; + case Tins::ARP::REPLY: + std::cout << "type: Reply" << std::endl; + break; + } + + std::cout << "target_hw_addr: " << arp.target_hw_addr() << std::endl; + std::cout << "target_ip_addr: " << arp.target_ip_addr() << std::endl; + std::cout << "sender_hw_addr: " << arp.sender_hw_addr() << std::endl; + std::cout << "sender_ip_addr: " << arp.sender_ip_addr() << std::endl; + std::cout << "@@@@@@@@@@@@@@@@@" << std::endl; +} + void nattest::checkAndPrintIp(const Tins::IP & ip, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp) { printIp(ip); checkIp(ip, targetDstIp, targetSrcIp); @@ -191,6 +353,11 @@ void nattest::checkAndPrintEth(const Tins::EthernetII & eth, const Tins::HWAddre checkEth(eth, targetDstMac, targetSrcMac, targetDstIp, targetSrcIp); } +void nattest::checkAndPrintArp(const Tins::ARP& arp, uint16_t targetArpType, const Tins::HWAddress<6>& targetTargetMac, const Tins::HWAddress<6>& targetSenderMac, const Tins::IPv4Address& targetTaregtIp, const Tins::IPv4Address& targetSenderIp) { + printArp(arp); + checkArp(arp, targetArpType, targetTargetMac, targetSenderMac, targetTaregtIp, targetSenderIp); +} + void nattest::checkIp(const Tins::IP & ip, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp) { const Tins::IPv4Address & packetSrcIp = ip.src_addr(); const Tins::IPv4Address & packetDstIp = ip.dst_addr(); @@ -203,6 +370,21 @@ void nattest::checkEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & const Tins::HWAddress<6> & frameDstMac = eth.dst_addr(); CPPUNIT_ASSERT_EQUAL(targetSrcMac, frameSrcMac); CPPUNIT_ASSERT_EQUAL(targetDstMac, frameDstMac); - checkIp(eth.rfind_pdu(), targetDstIp, targetSrcIp); + const Tins::IP * ip = eth.find_pdu(); + if (ip != nullptr) { + checkIp(*ip, targetDstIp, targetSrcIp); + } +} + +void nattest::checkArp(const Tins::ARP & arp, uint16_t targetArpType, const Tins::HWAddress<6> & targetTargetMac, const Tins::HWAddress<6> & targetSenderMac, const Tins::IPv4Address & targetTaregtIp, const Tins::IPv4Address & targetSenderIp) { + const Tins::HWAddress<6> & senderMac = arp.sender_hw_addr(); + const Tins::HWAddress<6> & targetMac = arp.target_hw_addr(); + const Tins::IPv4Address & senderIp = arp.sender_ip_addr(); + const Tins::IPv4Address & targetIp = arp.target_ip_addr(); + CPPUNIT_ASSERT_EQUAL(targetArpType, arp.opcode()); + CPPUNIT_ASSERT_EQUAL(targetSenderMac, senderMac); + CPPUNIT_ASSERT_EQUAL(targetTargetMac, targetMac); + CPPUNIT_ASSERT_EQUAL(targetSenderIp, senderIp); + CPPUNIT_ASSERT_EQUAL(targetTaregtIp, targetIp); } diff --git a/tests/nattest.h b/tests/nattest.h index 7b42bd1..ffc6ec4 100644 --- a/tests/nattest.h +++ b/tests/nattest.h @@ -21,6 +21,8 @@ class nattest : public CPPUNIT_NS::TestFixture { CPPUNIT_TEST(testIpCalcEth1); CPPUNIT_TEST(testIpCalcEth2); CPPUNIT_TEST(testForMeFromMe); + CPPUNIT_TEST(testTranslateArp); + CPPUNIT_TEST(testTranslateArpIp); CPPUNIT_TEST_SUITE_END(); public: @@ -63,14 +65,19 @@ private: void testIpCalcEth1(); void testIpCalcEth2(); void testTranslateIp(); + void testTranslateArp(); + void testTranslateArpIp(); void testForMeFromMe(); + void printArp(const Tins::ARP & arp); void printIp(const Tins::IP & ip); void printEth(const Tins::EthernetII & eth); void checkAndPrintIp(const Tins::IP & ip, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp); 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 checkAndPrintArp(const Tins::ARP & arp, uint16_t targetArpType, const Tins::HWAddress<6> & targetTargetMac, const Tins::HWAddress<6> & targetSenderMac, const Tins::IPv4Address & targetTaregtIp, const Tins::IPv4Address & targetSenderIp); void checkIp(const Tins::IP & ip, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp); void checkEth(const Tins::EthernetII & eth, const Tins::HWAddress<6> & targetDstMac, const Tins::HWAddress<6> & targetSrcMac, const Tins::IPv4Address & targetDstIp, const Tins::IPv4Address & targetSrcIp); + void checkArp(const Tins::ARP & arp, uint16_t targetArpType, const Tins::HWAddress<6> & targetTargetMac, const Tins::HWAddress<6> & targetSenderMac, const Tins::IPv4Address & targetTaregtIp, const Tins::IPv4Address & targetSenderIp); }; #endif /* NATTEST_H */