add arp tests and fix insert trnaslate

This commit is contained in:
stubbfel
2015-09-02 23:32:23 +02:00
parent 7560b71e92
commit 5476f0ea56
4 changed files with 309 additions and 69 deletions

View File

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

View File

@@ -13,7 +13,6 @@ namespace otonat {
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() {
@@ -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);
};

View File

@@ -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>(), 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>(), 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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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<Tins::EthernetII>(), "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>(), 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>(), 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>(), 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<Tins::IP>());
const Tins::IP * ip = eth.find_pdu<Tins::IP>();
if (ip != nullptr) {
printIp(*ip);
}
const Tins::ARP * arp = eth.find_pdu<Tins::ARP>();
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<Tins::IP>(), targetDstIp, targetSrcIp);
const Tins::IP * ip = eth.find_pdu<Tins::IP>();
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);
}

View File

@@ -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 */