diff --git a/build.sh b/build.bash similarity index 80% rename from build.sh rename to build.bash index aea8c88..3427495 100644 --- a/build.sh +++ b/build.bash @@ -1,7 +1,4 @@ #!/bin/bash -cd lib -sh buildalllibs.sh -cd .. mkdir -p build/121Natbuild cd build/121Natbuild cmake ../../ diff --git a/buildAll.bash b/buildAll.bash new file mode 100644 index 0000000..05ad001 --- /dev/null +++ b/buildAll.bash @@ -0,0 +1,5 @@ +#!/bin/bash +cd lib +sh buildalllibs.bash +cd .. +sh build.bash diff --git a/dist/package/PKGBUILD b/dist/package/PKGBUILD deleted file mode 100644 index 6b7cc31..0000000 --- a/dist/package/PKGBUILD +++ /dev/null @@ -1,47 +0,0 @@ -pkgname=121Nat -pkgver=1.0 # note: if the pkgver had been '0.99-10' then use an underscore. like '0.99_10' -pkgrel=1 -pkgdesc="transparent one to one nat" -arch=(any) -url="http://www.foo.org" -license=('MIT') -depends=('pth' 'libpcap' 'python2' 'jsoncpp') -makedepends=('cmake') -source=(./$pkgname-$pkgver.tar.gz) -md5sums=('0e1494ebbcf0b0ca1bfa8475c5078f21') - -build() { - cd "${srcdir}/${pkgname}" - cd lib - mkdir -p bin - # mkdir -p build/jsoncpp/ - # cd build/jsoncpp/ - # cmake ../../src/jsoncpp -DCMAKE_INSTALL_PREFIX=/usr - # make - # cp src/lib_json/libjsoncpp.a ../../bin - # cd ../.. - mkdir -p build/libtins/ - cd build/libtins/ - cmake ../../src/libtins -DLIBTINS_BUILD_SHARED=1 -DLIBTINS_ENABLE_CXX11=1 -DLIBTINS_ENABLE_WPA2=0 -DLIBTINS_ENABLE_DOT11=0 -DHAVE_PCAP_IMMEDIATE_MODE=1 -DCMAKE_INSTALL_PREFIX=/usr - make - cp lib/libtins.so ../../bin - cd ../../.. - mkdir -p build/121Natbuild - cd build/121Natbuild - cmake ../../ -DCMAKE_INSTALL_PREFIX=/usr - make - cp src/121Nat ../ -} - -package() { - #cd ${srcdir}/${pkgname}/lib/build/jsoncpp - #make DESTDIR="${pkgdir}" install - cd "${srcdir}/${pkgname}/lib/build/libtins" - make DESTDIR="${pkgdir}" install - cd "${srcdir}/${pkgname}/build/121Natbuild" - make DESTDIR="${pkgdir}" install - mkdir -p "${pkgdir}/etc/${pkgname}" - cp "../../src/config.json" "${pkgdir}/etc/${pkgname}/config-example.json" - rm -R "${pkgdir}/usr/CMake" -} -md5sums=('6d9edd32ba681731501820c5330bd692') diff --git a/dist/package/PKGBUILD.example b/dist/package/PKGBUILD.example deleted file mode 100644 index 1e5c810..0000000 --- a/dist/package/PKGBUILD.example +++ /dev/null @@ -1,46 +0,0 @@ -pkgname=121Nat -pkgver=1.0 # note: if the pkgver had been '0.99-10' then use an underscore. like '0.99_10' -pkgrel=1 -pkgdesc="transparent one to one nat" -arch=(any) -url="http://www.foo.org" -license=('MIT') -depends=('pth' 'libpcap' 'python2' 'jsoncpp') -makedepends=('cmake') -source=(./$pkgname-$pkgver.tar.gz) -md5sums=('0e1494ebbcf0b0ca1bfa8475c5078f21') - -build() { - cd "${srcdir}/${pkgname}" - cd lib - mkdir -p bin - # mkdir -p build/jsoncpp/ - # cd build/jsoncpp/ - # cmake ../../src/jsoncpp -DCMAKE_INSTALL_PREFIX=/usr - # make - # cp src/lib_json/libjsoncpp.a ../../bin - # cd ../.. - mkdir -p build/libtins/ - cd build/libtins/ - cmake ../../src/libtins -DLIBTINS_BUILD_SHARED=1 -DLIBTINS_ENABLE_CXX11=1 -DLIBTINS_ENABLE_WPA2=0 -DLIBTINS_ENABLE_DOT11=0 -DHAVE_PCAP_IMMEDIATE_MODE=1 -DCMAKE_INSTALL_PREFIX=/usr - make - cp lib/libtins.so ../../bin - cd ../../.. - mkdir -p build/121Natbuild - cd build/121Natbuild - cmake ../../ -DCMAKE_INSTALL_PREFIX=/usr - make - cp src/121Nat ../ -} - -package() { - #cd ${srcdir}/${pkgname}/lib/build/jsoncpp - #make DESTDIR="${pkgdir}" install - cd "${srcdir}/${pkgname}/lib/build/libtins" - make DESTDIR="${pkgdir}" install - cd "${srcdir}/${pkgname}/build/121Natbuild" - make DESTDIR="${pkgdir}" install - mkdir -p "${pkgdir}/etc/${pkgname}" - cp "../../src/config.json" "${pkgdir}/etc/${pkgname}/config-example.json" - rm -R "${pkgdir}/usr/CMake" -} diff --git a/dist/package/createpackage.sh b/dist/package/createpackage.sh deleted file mode 100644 index 8d9041f..0000000 --- a/dist/package/createpackage.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -mkdir -p temp/121Nat/lib - -cp -R ../../src/ temp/121Nat/ -cp -R ../../lib/src/ temp/121Nat/lib/ -cp ../../lib/*.sh temp/121Nat/lib/ -cp ../../build.sh temp/121Nat/ -cp ../../CMakeLists.txt temp/121Nat/ -cp PKGBUILD.example temp/PKGBUILD - -cd temp -tar -cvzf 121Nat-1.0.tar.gz 121Nat/ -md5=($(md5sum 121Nat-1.0.tar.gz)) -echo "md5sums=('$md5')" >> PKGBUILD -makepkg -cp *.pkg.tar.xz ../ -cp *.tar.gz ../ -cp -f PKGBUILD ../PKGBUILD -cd .. -rm -Rf temp diff --git a/lib/buildalllibs.bash b/lib/buildalllibs.bash new file mode 100644 index 0000000..5e85123 --- /dev/null +++ b/lib/buildalllibs.bash @@ -0,0 +1,3 @@ +#!/bin/bash +sh buildjsoncpp.bash +sh buildlibtins.bash diff --git a/lib/buildalllibs.sh b/lib/buildalllibs.sh deleted file mode 100644 index c4c3472..0000000 --- a/lib/buildalllibs.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -sh buildjsoncpp.sh -sh buildlibtins.sh diff --git a/lib/buildjsoncpp.sh b/lib/buildjsoncpp.bash similarity index 100% rename from lib/buildjsoncpp.sh rename to lib/buildjsoncpp.bash diff --git a/lib/buildlibtins.sh b/lib/buildlibtins.bash similarity index 100% rename from lib/buildlibtins.sh rename to lib/buildlibtins.bash diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk index 05ce4fc..19ce8b5 100644 --- a/nbproject/Makefile-Debug.mk +++ b/nbproject/Makefile-Debug.mk @@ -70,7 +70,7 @@ FFLAGS= ASFLAGS= # Link Libraries and Options -LDLIBSOPTIONS=-lpthread lib/bin/libjsoncpp.a -ltins +LDLIBSOPTIONS=-lpthread lib/bin/libjsoncpp.a lib/bin/libtins.so # Build Targets .build-conf: ${BUILD_SUBPROJECTS} @@ -78,6 +78,8 @@ LDLIBSOPTIONS=-lpthread lib/bin/libjsoncpp.a -ltins ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/121nat: lib/bin/libjsoncpp.a +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/121nat: lib/bin/libtins.so + ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/121nat: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/121nat ${OBJECTFILES} ${LDLIBSOPTIONS} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 3353544..2cac937 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -66,7 +66,7 @@ pthread lib/bin/libjsoncpp.a - tins + lib/bin/libtins.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0eb7a0..561e627 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ file(GLOB_RECURSE 121Nat_Src_Files "*.h" "*.cpp") add_executable(121Nat ${121Nat_Src_Files}) -target_link_libraries (121Nat pthread ${CMAKE_SOURCE_DIR}/lib/bin/libtins.so jsoncpp) +target_link_libraries (121Nat pthread ${CMAKE_SOURCE_DIR}/lib/bin/libtins.so ${CMAKE_SOURCE_DIR}/lib/bin/libjsoncpp.a) target_compile_features(121Nat PRIVATE cxx_range_for) install(TARGETS 121Nat RUNTIME DESTINATION bin diff --git a/src/PduSender.cpp b/src/PduSender.cpp index 5a6d6ae..c6141cd 100644 --- a/src/PduSender.cpp +++ b/src/PduSender.cpp @@ -15,7 +15,7 @@ namespace otonat { this->map = map; } - PduSender::PduSender(const PduSender& orig) : checksumList(orig.checksumList) { + PduSender::PduSender(const PduSender& orig) { this->map = orig.map; } @@ -23,7 +23,6 @@ namespace otonat { if (this == &rhs) return *this; // handle self assignment this->map = rhs.map; - this->checksumList = rhs.checksumList; return *this; } @@ -39,37 +38,30 @@ namespace otonat { std::cout << "send pdu:" << pdu->size() << std::endl; + bool isIp = false; + NatMap::Checksum ipCheckSum; Tins::IPv4Address dstIp = zeroIp; - const Tins::ARP * arp = pdu->find_pdu(); - bool isArp = false; - if (arp != nullptr) { - dstIp = arp->target_ip_addr(); - isArp = true; + const Tins::IP * ip = pdu->find_pdu(); + if (ip != nullptr) { + dstIp = ip->dst_addr(); + ipCheckSum = ip->checksum(); + isIp = true; } - if (!isArp) { - const Tins::IP * ip = pdu->find_pdu(); - if (ip != nullptr) { - dstIp = ip->dst_addr(); - - unsigned short int checkSum = ip->checksum(); - ChecksumList::const_iterator endIter = this->checksumList.end(); - ChecksumList::const_iterator beginIter = this->checksumList.begin(); - ChecksumList::const_iterator findIter = std::find(beginIter, endIter, checkSum); - if (endIter == findIter) { - this->checksumList.push_back(checkSum); - if (this->checksumList.size() > 10) { - this->checksumList.pop_front(); - } - } else { - continue; - } + if (!isIp) { + const Tins::ARP * arp = pdu->find_pdu(); + if (arp != nullptr) { + dstIp = arp->target_ip_addr(); } } 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; diff --git a/src/PduSender.h b/src/PduSender.h index b741533..9220e71 100644 --- a/src/PduSender.h +++ b/src/PduSender.h @@ -17,14 +17,11 @@ namespace otonat { class PduSender { public: - typedef std::list ChecksumList; - PduSender(NatMap * map); PduSender(const PduSender& orig); PduSender& operator=(const PduSender& rhs); virtual ~PduSender(); NatMap * map; - ChecksumList checksumList; void SendPdusFromQueue(); std::thread * SendPdusFromQueueThread(); diff --git a/src/map/natmap.cpp b/src/map/natmap.cpp index 4cc0d98..8181aff 100644 --- a/src/map/natmap.cpp +++ b/src/map/natmap.cpp @@ -9,6 +9,10 @@ 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(); @@ -24,7 +28,7 @@ namespace otonat { this->outgoingQueueMutex.unlock(); } - NatMap::NatMap(const NatMap& other) : ranges(other.ranges), transMap(other.transMap), reqIpMap(other.reqIpMap), incommingPduQueue(other.incommingPduQueue), outgoingPduQueue(other.outgoingPduQueue) { + 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::operator=(const NatMap& rhs) { @@ -38,6 +42,9 @@ namespace otonat { this->outgoingQueueMutex.lock(); outgoingPduQueue = rhs.outgoingPduQueue; this->outgoingQueueMutex.unlock(); + this->checksumListMutex.lock(); + this->checksumList = rhs.checksumList; + this->checksumListMutex.unlock(); return *this; } @@ -58,14 +65,19 @@ namespace otonat { } Tins::IP * ip = pduCopy->find_pdu(); - if (ip != nullptr) { - if (handleIp(ip, pduCopy)) { - this->pushPduToOutgoingPduQueue(pduCopy); - } + if (ip != nullptr && handleIp(ip, pduCopy)) { + + this->pushPduToOutgoingPduQueue(pduCopy); } } 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; @@ -92,6 +104,7 @@ namespace otonat { } else { const Tins::EthernetII * eth = originPDU->find_pdu(); if (eth != nullptr) { + Tins::EthernetII fakeArp = Tins::ARP::make_arp_request(ip->dst_addr(), ip->src_addr(), eth->src_addr()); SendTranslatedArpRequest(fakeArp.find_pdu()); } @@ -114,6 +127,7 @@ namespace otonat { // set translated src address transSrcAttr = transIpIter->second; } else { + transSrcAttr = InsertOrUdpateTranslateIpAddress(originSrc, transDstIp, ranges); } @@ -131,6 +145,7 @@ namespace otonat { const Tins::IPv4Range ipRange = range.calcIpRange(true); if (!ipRange.contains(otherTransSameRangeIp)) { + continue; } @@ -158,12 +173,12 @@ namespace otonat { if (transIpIter != transMap.end()) { transMap[transIp] = originIp; } else { + transMap.insert(IPv4AddressEntry(transIp, originIp)); } } bool NatMap::handleArp(Tins::ARP * arp) { - if (isForMeOrFromMeArp(arp)) { return false; } @@ -178,17 +193,20 @@ namespace otonat { return this->handleArpReq(arp); case Tins::ARP::REPLY: return this->handleArpReply(arp); + default: return false; } } bool NatMap::isForMeOrFromMeIp(const Tins::IP* ip) const { + return isForMeOrFromMeIp(ip, ranges); } bool NatMap::isForMeOrFromMeArp(const Tins::ARP * arp) const { Tins::IP fakeIp(arp->target_ip_addr(), arp->sender_ip_addr()); + return isForMeOrFromMeIp(&fakeIp); } @@ -198,6 +216,7 @@ namespace otonat { for (NatRange range : rangeList) { const Tins::IPv4Address & interfaceAddr = range.interface.info().ip_addr; if (srcAddr == interfaceAddr || dstAddr == interfaceAddr) { + return true; } } @@ -205,12 +224,14 @@ namespace otonat { } bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr) const { + return isIpInMyRanges(ipAddr, ranges); } bool NatMap::isIpInMyRanges(const Tins::IPv4Address & ipAddr, const NatRangeList & rangeList) { for (NatRange range : rangeList) { if (range.calcIpRange(false).contains(ipAddr)) { + return true; } } @@ -237,6 +258,7 @@ namespace otonat { if (transSenderIpIter != transMap.end()) { arp->sender_ip_addr(transSenderIpIter->second); this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); + return true; } @@ -249,7 +271,7 @@ namespace otonat { if (transSenderIpReqIter == reqIpMap.end()) { return false; } - + const Tins::IPv4Address transTargetIp = TranslateArpIp(targetIp); if (transTargetIp == zeroIp) { return false; @@ -263,6 +285,7 @@ namespace otonat { arp->target_ip_addr(transTargetIp); arp->sender_ip_addr(transSenderIp); + return true; } @@ -279,6 +302,7 @@ namespace otonat { this->InsertOrUdpateTranslateIpAddress(arpIp, transArpIp); this->InsertOrUdpateTranslateIpAddress(transArpIp, arpIp); this->reqIpMap.erase(transReqArpIpIter); + return transArpIp; } @@ -303,6 +327,7 @@ namespace otonat { IpAdressMap::const_iterator transSenderIpReqIter = this->reqIpMap.find(transSenderIp); if (transSenderIpReqIter == reqIpMap.end()) { + this->reqIpMap.insert(IPv4AddressEntry(transSenderIp, senderIp)); } @@ -335,6 +360,7 @@ namespace otonat { IpAdressMap::const_iterator transTargetIpReqIter = this->reqIpMap.find(transTargetIp); if (transTargetIpReqIter == reqIpMap.end()) { + this->reqIpMap.insert(IPv4AddressEntry(transTargetIp, targetIp)); } @@ -344,18 +370,22 @@ namespace otonat { } void NatMap::pushPduToIncommingPduQueue(const Tins::PDU* pdu) { + pushPduToPduQueue(pdu, this->incommingPduQueue, this ->incommingQueueMutex); } Tins::PDU * NatMap::popPduIncommingPduQueue() { + return popPduPduQueue(this->incommingPduQueue, this->incommingQueueMutex); } void NatMap::pushPduToOutgoingPduQueue(const Tins::PDU* pdu) { + pushPduToPduQueue(pdu, this->outgoingPduQueue, this->outgoingQueueMutex); } Tins::PDU * NatMap::popPduOutgoingPduQueue() { + return popPduPduQueue(this->outgoingPduQueue, this->outgoingQueueMutex); } @@ -371,10 +401,12 @@ namespace otonat { queue.pop(); mtx.unlock(); delete result; + return outPut; } void NatMap::pushPduToPduQueue(const Tins::PDU* pdu, PduQueue& queue, std::mutex& mtx) { + mtx.lock(); queue.push(pdu); mtx.unlock(); @@ -384,6 +416,7 @@ namespace otonat { while (true) { Tins::PDU * pdu = this->popPduIncommingPduQueue(); if (pdu == nullptr) { + continue; } @@ -391,6 +424,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; diff --git a/src/map/natmap.h b/src/map/natmap.h index 97a3738..aff9af4 100644 --- a/src/map/natmap.h +++ b/src/map/natmap.h @@ -18,6 +18,9 @@ namespace otonat { typedef std::queue PduQueue; typedef std::pair IPv4AddressEntry; typedef std::map IpAdressMap; + typedef unsigned short int Checksum; + typedef std::list ChecksumList; + NatMap() { } @@ -38,7 +41,8 @@ namespace otonat { Tins::PDU * popPduIncommingPduQueue(); void pushPduToOutgoingPduQueue(const Tins::PDU * pdu); Tins::PDU * popPduOutgoingPduQueue(); - + void pushCheckSumToList(Checksum checksum); + static Tins::PDU * popPduPduQueue(PduQueue & queue, std::mutex & mtx); static void pushPduToPduQueue(const Tins::PDU * pdu, PduQueue & queue, std::mutex & mtx); @@ -61,9 +65,12 @@ 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; }; }