add hw adress translator, add solicitedNodeAddress traslation , finisched arp to ndp handler

This commit is contained in:
stubbfel
2017-02-16 00:47:27 +01:00
parent 7e7e66f0b7
commit 9b65fca64a
9 changed files with 140 additions and 123 deletions

View File

@@ -6,19 +6,26 @@
#include <tins/ipv6.h>
#include <tins/ip_address.h>
#include <tins/ipv6_address.h>
#include "HwAddressTranslator.h"
#include "IpAddressTranslator.h"
ArpToNdpPacketHandler::ArpToNdpPacketHandler(const Tins::IPv6Address & newPrefix)
{
prefix = std::make_unique<Tins::IPv6Address>(newPrefix);
ndpPrefix = std::make_unique<Tins::IPv6Address>("FF02:0:0:0:0:1:FF");
ndpMask = std::make_unique<Tins::IPv4Address>("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>();
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<Tins::IPv6Address>(*prefix);
UPtrIPv6Address senderIp6Address = std::make_unique<Tins::IPv6Address>(*prefix);
UPtrIPv6Address targetIp6Address = std::make_unique<Tins::IPv6Address>(*prefix);
IpAddressTranslator::toIpv6Address(arpPdu->sender_ip_addr(), *srcIp6Address);
IpAddressTranslator::toIpv6Address(arpPdu->target_ip_addr(), *targetIp6Address);
// create ip4 pdu
std::unique_ptr<const Tins::IPv6> ipv6Pdu = std::make_unique<const Tins::IPv6>((*targetIp6Address)|(*ndpPrefix),*srcIp6Address);
std::unique_ptr<Tins::ICMPv6> 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<Tins::ICMPv6> ndpPdu;
std::shared_ptr<Tins::IPv6> ipv6Pdu = std::make_shared<Tins::IPv6>();
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>(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>(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<Tins::EthernetII> ptrForwardEthPdu = std::make_unique<Tins::EthernetII>();
Tins::EthernetII & forwardEthPdu = *ptrForwardEthPdu;
// copy src and dst mac address
std::shared_ptr<Tins::PDU> ptrOutestPdu;
const Tins::EthernetII * ethPdu = pdu.find_pdu<Tins::EthernetII>();
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<Tins::EthernetII> ptrEthPdu = std::make_shared<Tins::EthernetII>();
ptrEthPdu->src_addr(ethPdu->src_addr());
Tins::EthernetII::address_type dstMac;
if (isRequest)
{
// set solicited address
UPtrHwAddress solicitedNodeHWAddress = std::make_unique<HwAddress>();
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

View File

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

View File

@@ -0,0 +1,29 @@
#include "HwAddressTranslator.h"
#include <tins/ipv6_address.h>
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--;
}
}

27
src/HwAddressTranslator.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef HWADDRESSTRANSLATOR_H
#define HWADDRESSTRANSLATOR_H
#include <cstddef>
#include <stdint.h>
#include <tins/hw_address.h>
#include "Main_t.h"
#include "Ip6Packet_t.h"
#ifndef DefaultSizeOf
#define DefaultSizeOfHwAddress 6
#endif
typedef Tins::HWAddress<DefaultSizeOfHwAddress> HwAddress;
typedef std::unique_ptr<HwAddress> UPtrHwAddress;
class HwAddressTranslator
{
public:
static void toSolicitedNodeAddress(IN const Tins::IPv6Address & ipv6Address, INOUT HwAddress & resultHwAddress);
private:
static const uint8_t solicitedNodeAddressPrefix[];
};
#endif

View File

@@ -6,6 +6,7 @@
namespace Tins
{
class IPv6Address;
class IPv6;
}
typedef std::unique_ptr<Tins::IPv6Address> UPtrIPv6Address;

View File

@@ -2,7 +2,28 @@
#include <tins/ip_address.h>
#include <tins/ipv6_address.h>
#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<Tins::IPv6Address>(NdpPrefixValueString);
const UPtrIPv6Address IpAddressTranslator::ndpMask = std::make_unique<Tins::IPv6Address>(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)
{

View File

@@ -4,19 +4,19 @@
#include <cstddef>
#include <stdint.h>
#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

View File

@@ -1,93 +1,7 @@
#include <iostream>
#include <vector>
#include <string>
#include <tuple>
#include "Main_t.h"
void tprintf(const char* format) // base function
{
std::cout << format;
}
template<typename T, typename... Targs>
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<typename... Ts> 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<int> dummy = { (args, args)... };
int size2 = dummy.size();
size2++;
}
struct foo{
int bar = 0;
float bla = 3.12;
std::string blub = "blub";
};
template<typename... Ts>
class varicdclass{
public:
explicit varicdclass(Ts*... mixins)
{
fillList(mixins...);
}
template<typename T>
void fillList(T * arg){
dummy.push_back(arg == nullptr ? new T() : arg);
}
template<typename T,typename... Us>
void fillList(T * arg, Us*... args){
dummy.push_back(arg == nullptr ? new T() : arg);
fillList(args...);
}
std::vector<void*> dummy;
template<typename T>
int bar (T i) {return 0;}
template<typename T>
int bar (int i) {return 1;}
template<typename T>
int bar (float f) {return 2;}
};
class dervaricdclass : public varicdclass<int, double, foo>
{
public:
dervaricdclass() : varicdclass(nullptr,nullptr,nullptr)
{
}
};
int main()
{
tprintf("% world% %\n","Hello",'!',123);
func<int,int,int, int>(0,0,1,0);
int i = 1;
double d = 3.21;
foo f;
varicdclass<foo, int, double> dvc(&f,&i, &d);
varicdclass<int, double, foo> dvc2(nullptr,nullptr,nullptr);
dervaricdclass dvc3;
i++;
int l = dvc3.bar(1);
int j = dvc3.bar(1.0);
int k = dvc3.bar('1');
i++;
}