diff --git a/lib/libtins b/lib/libtins index c9dea75..25c8802 160000 --- a/lib/libtins +++ b/lib/libtins @@ -1 +1 @@ -Subproject commit c9dea752431ac5aa7dbbb374e73b5e459113437f +Subproject commit 25c8802f621a75f04130eb7206f90cd15513c596 diff --git a/src/ArpToNdpPacketHandler.cpp b/src/ArpToNdpPacketHandler.cpp index d100a42..2ba7da3 100644 --- a/src/ArpToNdpPacketHandler.cpp +++ b/src/ArpToNdpPacketHandler.cpp @@ -6,19 +6,26 @@ #include #include #include +#include "HwAddressTranslator.h" #include "IpAddressTranslator.h" ArpToNdpPacketHandler::ArpToNdpPacketHandler(const Tins::IPv6Address & newPrefix) { prefix = std::make_unique(newPrefix); - ndpPrefix = std::make_unique("FF02:0:0:0:0:1:FF"); - ndpMask = std::make_unique("255.0.0.0"); } ArpToNdpPacketHandler::~ArpToNdpPacketHandler() { } +void ArpToNdpPacketHandler::setSolicitedNodeAddress(INOUT Tins::IPv6 & ipv6, IN const Tins::IPv6Address & targetIp) +{ + UPtrIPv6Address solicitedNodeAddress = std::make_unique(); + Tins::IPv6Address & tmpRef = *solicitedNodeAddress; + IpAddressTranslator::toSolicitedNodeAddress(targetIp, tmpRef); + ipv6.dst_addr(tmpRef); +} + bool ArpToNdpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * callBackHandler) { // callback handvet requeried @@ -35,50 +42,69 @@ bool ArpToNdpPacketHandler::handle(IN const Tins::PDU & pdu, IN IPacketHandler * } // convert ipv4 addresses to ipv6 addresses - - UPtrIPv6Address srcIp6Address = std::make_unique(*prefix); + UPtrIPv6Address senderIp6Address = std::make_unique(*prefix); UPtrIPv6Address targetIp6Address = std::make_unique(*prefix); - IpAddressTranslator::toIpv6Address(arpPdu->sender_ip_addr(), *srcIp6Address); - IpAddressTranslator::toIpv6Address(arpPdu->target_ip_addr(), *targetIp6Address); - // create ip4 pdu - std::unique_ptr ipv6Pdu = std::make_unique((*targetIp6Address)|(*ndpPrefix),*srcIp6Address); - std::unique_ptr ndpPdu; + const Tins::IPv4Address & targetIp =arpPdu->target_ip_addr(); + IpAddressTranslator::toIpv6Address(arpPdu->sender_ip_addr(), *senderIp6Address); + IpAddressTranslator::toIpv6Address(targetIp, *targetIp6Address); + // create ip4 pdu + std::unique_ptr ndpPdu; + std::shared_ptr ipv6Pdu = std::make_shared(); + ipv6Pdu->src_addr(*senderIp6Address); + bool isRequest = false; + const Tins::ARP::hwaddress_type & senderHwAddr = arpPdu->sender_hw_addr(); switch (arpPdu->opcode()) { case Tins::ARP::REQUEST: ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_SOLICIT); + setSolicitedNodeAddress(*ipv6Pdu, *targetIp6Address); + ndpPdu->source_link_layer_addr(senderHwAddr); + ndpPdu->target_addr(*targetIp6Address); + isRequest = true; break; + case Tins::ARP::REPLY: ndpPdu = std::make_unique(Tins::ICMPv6::NEIGHBOUR_ADVERT); + ipv6Pdu->dst_addr(*targetIp6Address); + ndpPdu->target_addr(*senderIp6Address); + ndpPdu->target_link_layer_addr(senderHwAddr); break; default: return false; } - ndpPdu->target_addr(*targetIp6Address); - // create forwarding frame - std::unique_ptr ptrForwardEthPdu = std::make_unique(); - Tins::EthernetII & forwardEthPdu = *ptrForwardEthPdu; - - // copy src and dst mac address + std::shared_ptr ptrOutestPdu; const Tins::EthernetII * ethPdu = pdu.find_pdu(); if(ethPdu != nullptr) { - // @todo to set multicast - forwardEthPdu.src_addr(ethPdu->src_addr()); - Tins::IPv4Address foo =arpPdu->target_ip_addr(); - std::string string("hello $name"); - Tins::EthernetII::address_type ethernatMask = std::regex_replace("00:00:" + foo.to_string(), std::regex("."), ":"); - Tins::EthernetII::address_type ethernatMask2 = "33:33:FF:00:00:00"; - forwardEthPdu.dst_addr(ethernatMask | ethernatMask2); + // set eth frame + std::shared_ptr ptrEthPdu = std::make_shared(); + ptrEthPdu->src_addr(ethPdu->src_addr()); + Tins::EthernetII::address_type dstMac; + if (isRequest) + { + // set solicited address + UPtrHwAddress solicitedNodeHWAddress = std::make_unique(); + HwAddressTranslator::toSolicitedNodeAddress(*targetIp6Address, *solicitedNodeHWAddress); + ptrEthPdu->dst_addr(*solicitedNodeHWAddress); + } + else + { + ptrEthPdu->dst_addr(ethPdu->dst_addr()); + } + + ptrOutestPdu = ptrEthPdu; + *ptrOutestPdu /= *ipv6Pdu; + } + else + { + ptrOutestPdu = ipv6Pdu; } - forwardEthPdu /= *ipv6Pdu; - forwardEthPdu /= *ndpPdu; - - // forward frame - return callBackHandler->handle(forwardEthPdu, this); + Tins::PDU & outestPdu = *ptrOutestPdu; + outestPdu /= *ndpPdu; + return callBackHandler->handle(outestPdu, this); } const Tins::IPv6Address & ArpToNdpPacketHandler::getPrefix() const diff --git a/src/ArpToNdpPacketHandler.h b/src/ArpToNdpPacketHandler.h index 1fd0eb0..f4e729b 100644 --- a/src/ArpToNdpPacketHandler.h +++ b/src/ArpToNdpPacketHandler.h @@ -17,9 +17,8 @@ public: const Tins::IPv6Address & getPrefix() const; void setPrefix(const Tins::IPv6Address & newPrefix); + void setSolicitedNodeAddress(INOUT Tins::IPv6 & ipv6, IN const Tins::IPv6Address & targetIp); private: UPtrIPv6Address prefix; - UPtrIPv6Address ndpPrefix; - UPtrIPv4Address ndpMask; }; #endif diff --git a/src/HwAddressTranslator.cpp b/src/HwAddressTranslator.cpp new file mode 100644 index 0000000..8a4130c --- /dev/null +++ b/src/HwAddressTranslator.cpp @@ -0,0 +1,29 @@ +#include "HwAddressTranslator.h" +#include + + +const uint8_t HwAddressTranslator::solicitedNodeAddressPrefix[] = {0x33, 0x33, 0xff}; + +void HwAddressTranslator::toSolicitedNodeAddress(IN const Tins::IPv6Address &ipv6Address, INOUT HwAddress &resultHwAddress) +{ + Tins::IPv6Address::const_iterator ipv6It = ipv6Address.end(); + HwAddress::iterator hwIt = resultHwAddress.end(); + + hwIt--; + ipv6It--; + + // copy last 3 bydes of ip v6 to hw address + for (int i = 0; i < 3; i++) + { + *hwIt = *ipv6It; + hwIt--; + ipv6It--; + } + + // copy solicited Address prefix to hw address + for (int j = 2; j > -1; j--) + { + *hwIt = solicitedNodeAddressPrefix[j]; + hwIt--; + } +} diff --git a/src/HwAddressTranslator.h b/src/HwAddressTranslator.h new file mode 100644 index 0000000..935a637 --- /dev/null +++ b/src/HwAddressTranslator.h @@ -0,0 +1,27 @@ +#ifndef HWADDRESSTRANSLATOR_H +#define HWADDRESSTRANSLATOR_H + +#include +#include +#include +#include "Main_t.h" +#include "Ip6Packet_t.h" + + +#ifndef DefaultSizeOf +#define DefaultSizeOfHwAddress 6 +#endif + + +typedef Tins::HWAddress HwAddress; +typedef std::unique_ptr UPtrHwAddress; + +class HwAddressTranslator +{ + +public: + static void toSolicitedNodeAddress(IN const Tins::IPv6Address & ipv6Address, INOUT HwAddress & resultHwAddress); +private: + static const uint8_t solicitedNodeAddressPrefix[]; +}; +#endif diff --git a/src/Ip6Packet_t.h b/src/Ip6Packet_t.h index d41f734..e7c76fa 100644 --- a/src/Ip6Packet_t.h +++ b/src/Ip6Packet_t.h @@ -6,6 +6,7 @@ namespace Tins { class IPv6Address; + class IPv6; } typedef std::unique_ptr UPtrIPv6Address; diff --git a/src/IpAddressTranslator.cpp b/src/IpAddressTranslator.cpp index 588ba22..1ed95a7 100644 --- a/src/IpAddressTranslator.cpp +++ b/src/IpAddressTranslator.cpp @@ -2,7 +2,28 @@ #include #include +#ifndef NdpPrefixValueString +#define NdpPrefixValueString "FF02:0:0:0:0:1:FF00:0" +#endif + +#ifndef NdpMaskValueString +#define NdpMaskValueString "::FF:FFFF" +#endif + const size_t IpAddressTranslator::lastAddressByteIndex = Tins::IPv4Address::address_size - 1; +const UPtrIPv6Address IpAddressTranslator::ndpPrefix = std::make_unique(NdpPrefixValueString); +const UPtrIPv6Address IpAddressTranslator::ndpMask = std::make_unique(NdpMaskValueString); + +void IpAddressTranslator::toSolicitedNodeAddress(const Tins::IPv4Address &ipv4Address, Tins::IPv6Address &resultIpv6Address) +{ + toIpv6Address(ipv4Address, resultIpv6Address); + toSolicitedNodeAddress(resultIpv6Address, resultIpv6Address); +} + +void IpAddressTranslator::toSolicitedNodeAddress(const Tins::IPv6Address &ipv6Address, Tins::IPv6Address &resultIpv6Address) +{ + resultIpv6Address = (*ndpMask & ipv6Address)| *ndpPrefix; +} uint32_t IpAddressTranslator::toIpv4AddressBytes(IN const Tins::IPv6Address & ipv6Address) { diff --git a/src/IpAddressTranslator.h b/src/IpAddressTranslator.h index daf8ad6..a94a0d2 100644 --- a/src/IpAddressTranslator.h +++ b/src/IpAddressTranslator.h @@ -4,19 +4,19 @@ #include #include #include "Main_t.h" - -namespace Tins -{ - class IPv4Address; - class IPv6Address; -} +#include "Ip6Packet_t.h" +#include "Ip4Packet_t.h" class IpAddressTranslator { public: static void toIpv6Address(IN const Tins::IPv4Address & ipv4Address, INOUT Tins::IPv6Address & resultIpv6Address); + static void toSolicitedNodeAddress(IN const Tins::IPv4Address & ipv4Address, INOUT Tins::IPv6Address & resultIpv6Address); + static void toSolicitedNodeAddress(IN const Tins::IPv6Address & ipv6Address, INOUT Tins::IPv6Address & resultIpv6Address); static uint32_t toIpv4AddressBytes(IN const Tins::IPv6Address & ipv6Address); private: static const size_t lastAddressByteIndex; + static const UPtrIPv6Address ndpPrefix; + static const UPtrIPv6Address ndpMask; }; #endif diff --git a/src/Main.cpp b/src/Main.cpp index 7c79112..1cd6f0b 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,93 +1,7 @@ -#include -#include -#include -#include +#include "Main_t.h" -void tprintf(const char* format) // base function -{ - std::cout << format; -} - -template -void tprintf(const char* format, T value, Targs... Fargs) // recursive variadic function -{ - for ( ; *format != '\0'; format++ ) { - if ( *format == '%' ) { - std::cout << value; - tprintf(format+1, Fargs...); // recursive call - return; - } - std::cout << *format; - } -} - -template void func(Ts... args){ - const int size = sizeof...(Ts); -/* int res[size] = {1,args...,2}; - // since initializer lists guarantee sequencing, this can be used to - // call a function on each element of a pack, in order*/ - std::vector dummy = { (args, args)... }; - int size2 = dummy.size(); - size2++; -} - -struct foo{ - int bar = 0; - float bla = 3.12; - std::string blub = "blub"; -}; - -template -class varicdclass{ -public: - - explicit varicdclass(Ts*... mixins) - { - fillList(mixins...); - } - - template - void fillList(T * arg){ - dummy.push_back(arg == nullptr ? new T() : arg); - } - - template - void fillList(T * arg, Us*... args){ - dummy.push_back(arg == nullptr ? new T() : arg); - fillList(args...); - } - std::vector dummy; - - template - int bar (T i) {return 0;} - template - int bar (int i) {return 1;} - template - int bar (float f) {return 2;} -}; - -class dervaricdclass : public varicdclass -{ -public: - dervaricdclass() : varicdclass(nullptr,nullptr,nullptr) - { - } -}; int main() { - tprintf("% world% %\n","Hello",'!',123); - func(0,0,1,0); - int i = 1; - double d = 3.21; - foo f; - varicdclass dvc(&f,&i, &d); - varicdclass dvc2(nullptr,nullptr,nullptr); - dervaricdclass dvc3; - i++; - int l = dvc3.bar(1); - int j = dvc3.bar(1.0); - int k = dvc3.bar('1'); - i++; }