finish ipv6 fragmentation
This commit is contained in:
Submodule lib/libtins updated: f06a508b2c...06001815ae
@@ -1,6 +1,7 @@
|
||||
#ifndef INETWORKINTERFACECARD_H
|
||||
#define INETWORKINTERFACECARD_H
|
||||
|
||||
#include "INetworkInterfaceCard_t.h"
|
||||
#include "IPacketHandler.h"
|
||||
|
||||
interface INetworkInterfaceCard : IPacketHandler
|
||||
@@ -8,5 +9,6 @@ interface INetworkInterfaceCard : IPacketHandler
|
||||
virtual void sendPacket(IN const Tins::PDU & pdu) = 0;
|
||||
virtual void startListen() = 0;
|
||||
virtual void stopListen() = 0;
|
||||
virtual size_t getMtu() const = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include <memory>
|
||||
#include "Main_t.h"
|
||||
|
||||
#ifndef DEFAULT_MTU_VAULE
|
||||
#define DEFAULT_MTU_VAULE 1500
|
||||
#endif
|
||||
|
||||
interface IPacketHandler;
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "IpPacketFragmentation.h"
|
||||
#include <algorithm>
|
||||
#include <tins/ipv6.h>
|
||||
#include <tins/rawpdu.h>
|
||||
#include <tins/tcp.h>
|
||||
|
||||
const size_t IpPacketFragmentation::fragmentionHeadersize = sizeof (FragmentionHeaderUnion) - 1;
|
||||
|
||||
@@ -16,13 +18,13 @@ IpPacketFragmentation::~IpPacketFragmentation()
|
||||
|
||||
void IpPacketFragmentation::addExtensionHeader(IN const uint8_t nextHeader, IN const uint8_t *startPtr, IN Tins::IPv6 & ipFragmentPdu, const size_t headersize)
|
||||
{
|
||||
Tins::IPv6::ext_header extensionHeader(nextHeader, headersize , startPtr);
|
||||
Tins::IPv6::ext_header extensionHeader(nextHeader, 6 , startPtr);
|
||||
ipFragmentPdu.add_ext_header(extensionHeader);
|
||||
}
|
||||
|
||||
void IpPacketFragmentation::initFragmentationHeader(FragmentionHeaderStruct* ptrFragmentionHeaderStruct)
|
||||
{
|
||||
ptrFragmentionHeaderStruct->NextHeader = Tins::IPv6::FRAGMENT;
|
||||
ptrFragmentionHeaderStruct->NextHeader = Tins::Constants::IP::PROTO_TCP;
|
||||
ptrFragmentionHeaderStruct->Reserved = 0;
|
||||
ptrFragmentionHeaderStruct->Res = 0;
|
||||
ptrFragmentionHeaderStruct->MFlag = 1;
|
||||
@@ -43,7 +45,7 @@ bool IpPacketFragmentation::handle(IN const Tins::PDU & pdu, IN IPacketHandler *
|
||||
return callBackHandler->handle(pdu, this);
|
||||
}
|
||||
|
||||
const Tins::IPv6 * ipPdu = pdu.find_pdu<Tins::IPv6>();
|
||||
Tins::IPv6 * ipPdu = pdu.clone()->find_pdu<Tins::IPv6>();
|
||||
if (ipPdu == nullptr)
|
||||
{
|
||||
return false;
|
||||
@@ -55,30 +57,41 @@ bool IpPacketFragmentation::handle(IN const Tins::PDU & pdu, IN IPacketHandler *
|
||||
return false;
|
||||
}
|
||||
|
||||
ByteVector ipPayload = ipDataPdu->serialize();
|
||||
ByteVector ipPayload2 = ipPdu->serialize();
|
||||
ByteVector ipPayload(ipPayload2.begin() + ipPdu->header_size(), ipPayload2.end());
|
||||
uint8_t originNextHeader = ipPdu->next_header();
|
||||
const long ipPayloadSize = static_cast<const long>(ipPayload.size());
|
||||
const long fragmentationSize = static_cast<const long>(ipPayload.size() / fragmentationCount);
|
||||
const long fragmentationSize64B = (ipPayloadSize/ static_cast<const long>(fragmentationCount)) / 64;
|
||||
const long fragmentationSize = fragmentationSize64B * 64;
|
||||
const long payLoadEndIndicator = ipPayloadSize - fragmentationSize;
|
||||
ByteVector::iterator fragmentPosIt = ipPayload.begin();
|
||||
FragmentionHeaderUnion fragmentionHeaderUnion;
|
||||
FragmentionHeaderStruct * ptrFragmentionHeaderStruct = &fragmentionHeaderUnion.Structed;
|
||||
uint8_t * ptrStartFragmentionHeader = &fragmentionHeaderUnion.Bytes[1];
|
||||
uint8_t * ptrStartFragmentionHeader = &fragmentionHeaderUnion.Bytes[2];
|
||||
initFragmentationHeader(ptrFragmentionHeaderStruct);
|
||||
for (ptrFragmentionHeaderStruct->FragmentOffset = 0; ptrFragmentionHeaderStruct->FragmentOffset < payLoadEndIndicator; ptrFragmentionHeaderStruct->FragmentOffset += fragmentationSize)
|
||||
|
||||
long frameOffset;
|
||||
for (frameOffset = 0; frameOffset < payLoadEndIndicator; frameOffset += fragmentationSize)
|
||||
{
|
||||
ByteVector::iterator fragmentStart = fragmentPosIt;
|
||||
fragmentPosIt = fragmentStart + fragmentationSize;
|
||||
if (!createAndForwardFragmend(pdu, fragmentStart, fragmentPosIt, ptrFragmentionHeaderStruct, ptrStartFragmentionHeader, callBackHandler))
|
||||
ptrFragmentionHeaderStruct->FragmentOffset = static_cast<uint16_t>(frameOffset) / 8;
|
||||
std::swap(fragmentionHeaderUnion.Bytes[2],fragmentionHeaderUnion.Bytes[3]);
|
||||
if (!createAndForwardFragmend(originNextHeader,pdu, fragmentStart, fragmentPosIt, ptrFragmentionHeaderStruct, ptrStartFragmentionHeader, callBackHandler))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::swap(fragmentionHeaderUnion.Bytes[2],fragmentionHeaderUnion.Bytes[3]);
|
||||
}
|
||||
|
||||
ptrFragmentionHeaderStruct->MFlag = 0;
|
||||
return createAndForwardFragmend(pdu, fragmentPosIt, ipPayload.end(), ptrFragmentionHeaderStruct, ptrStartFragmentionHeader, callBackHandler);
|
||||
ptrFragmentionHeaderStruct->FragmentOffset = static_cast<uint16_t>(frameOffset) / 8;
|
||||
std::swap(fragmentionHeaderUnion.Bytes[2],fragmentionHeaderUnion.Bytes[3]);
|
||||
return createAndForwardFragmend(originNextHeader, pdu, fragmentPosIt, ipPayload.end(), ptrFragmentionHeaderStruct, ptrStartFragmentionHeader, callBackHandler);
|
||||
}
|
||||
|
||||
bool IpPacketFragmentation::createAndForwardFragmend(IN const Tins::PDU & pdu, IN const ByteVector::iterator & fragmentStart, IN const ByteVector::iterator & fragmentPosIt, IN FragmentionHeaderStruct * ptrFragmentionHeaderStruct, IN uint8_t * ptrStartFragmentionHeader, IN IPacketHandler * callBackHandler)
|
||||
bool IpPacketFragmentation::createAndForwardFragmend(IN const uint8_t originNextHeader, IN const Tins::PDU & pdu, IN const ByteVector::iterator & fragmentStart, IN const ByteVector::iterator & fragmentPosIt, IN FragmentionHeaderStruct * ptrFragmentionHeaderStruct, IN uint8_t * ptrStartFragmentionHeader, IN IPacketHandler * callBackHandler)
|
||||
{
|
||||
SPtrByteVector fragmentPayload = std::make_shared<ByteVector>(fragmentStart, fragmentPosIt);
|
||||
Tins::PDU * fragmentPdu = pdu.clone();
|
||||
@@ -93,11 +106,9 @@ bool IpPacketFragmentation::createAndForwardFragmend(IN const Tins::PDU & pdu, I
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tins::IPv6::ext_header fragmentionHeader(ptrFragmentionHeaderStruct->NextHeader, IpPacketFragmentation::fragmentionHeadersize , ptrStartFragmentionHeader);
|
||||
// ipFragmentPdu->add_ext_header(fragmentionHeader);
|
||||
addExtensionHeader(ptrFragmentionHeaderStruct->NextHeader, ptrStartFragmentionHeader, *ipFragmentPdu, IpPacketFragmentation::fragmentionHeadersize);
|
||||
addExtensionHeader(Tins::IPv6::NO_NEXT_HEADER, nullptr, *ipFragmentPdu, 0);
|
||||
addExtensionHeader(originNextHeader, ptrStartFragmentionHeader, *ipFragmentPdu, IpPacketFragmentation::fragmentionHeadersize);
|
||||
SPtrRawPDU rawFragmentPdu = std::make_shared<Tins::RawPDU>(fragmentPayload->data(), static_cast<uint32_t>(fragmentPayload->size()));
|
||||
ipFragmentPdu->inner_pdu(rawFragmentPdu.get());
|
||||
ipFragmentPdu->next_header(Tins::IPv6::FRAGMENT);
|
||||
return callBackHandler->handle(*fragmentPdu, this);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ private:
|
||||
uint32_t idCounter;
|
||||
static const size_t fragmentionHeadersize;
|
||||
static void addExtensionHeader(IN const uint8_t NextHeader, IN const uint8_t *startPtr, IN Tins::IPv6 & ipFragmentPdu, IN const size_t headersize);
|
||||
bool createAndForwardFragmend(IN const Tins::PDU & pdu, IN const ByteVector::iterator & fragmentStart, IN const ByteVector::iterator & fragmentPosIt, IN FragmentionHeaderStruct * ptrFragmentionHeaderStruct, IN uint8_t * ptrStartFragmentionHeader, IN IPacketHandler * callBackHandler);
|
||||
bool createAndForwardFragmend(IN const uint8_t originNextHeader, IN const Tins::PDU & pdu, IN const ByteVector::iterator & fragmentStart, IN const ByteVector::iterator & fragmentPosIt, IN FragmentionHeaderStruct * ptrFragmentionHeaderStruct, IN uint8_t * ptrStartFragmentionHeader, IN IPacketHandler * callBackHandler);
|
||||
|
||||
void initFragmentationHeader(FragmentionHeaderStruct* ptrFragmentionHeaderStruct);
|
||||
};
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
class IpPacketFragmentation;
|
||||
typedef IpPacketFragmentation * PtrIpPacketFragmentation;
|
||||
typedef std::shared_ptr<IpPacketFragmentation> * SPtrIpPacketFragmentation;
|
||||
typedef std::unique_ptr<IpPacketFragmentation> * UPtrIpPacketFragmentation;
|
||||
typedef std::weak_ptr<IpPacketFragmentation> * WPtrIpPacketFragmentation;
|
||||
typedef std::shared_ptr<IpPacketFragmentation> SPtrIpPacketFragmentation;
|
||||
typedef std::unique_ptr<IpPacketFragmentation> UPtrIpPacketFragmentation;
|
||||
typedef std::weak_ptr<IpPacketFragmentation> WPtrIpPacketFragmentation;
|
||||
|
||||
namespace Tins
|
||||
{
|
||||
@@ -36,5 +36,20 @@ union FragmentionHeaderUnion
|
||||
uint8_t Bytes[8];
|
||||
};
|
||||
|
||||
|
||||
struct tcp_header_s {
|
||||
uint16_t sport;
|
||||
uint16_t dport;
|
||||
uint32_t seq;
|
||||
uint32_t ack_seq;
|
||||
uint8_t doff:4,
|
||||
res1:4;
|
||||
union {
|
||||
uint8_t flags_8;
|
||||
};
|
||||
uint16_t window;
|
||||
uint16_t check;
|
||||
uint16_t urg_ptr;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#endif // IPPACKETFRAGMENTATION_T_H
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#include <tins/ip.h>
|
||||
#include <tins/ipv6.h>
|
||||
#include "INetworkInterfaceCard.h"
|
||||
#include "IpPacketFragmentation.h"
|
||||
|
||||
IpVersionRouter::IpVersionRouter(SPtrINetworkInterfaceCard netv4Card, SPtrINetworkInterfaceCard netv6Card)
|
||||
{
|
||||
ipv4Card = netv4Card;
|
||||
ipv6Card = netv6Card;
|
||||
ipv6Fragmentation = std::make_unique<IpPacketFragmentation>(ipv6Card->getMtu());
|
||||
}
|
||||
|
||||
IpVersionRouter::~IpVersionRouter()
|
||||
@@ -19,8 +21,13 @@ bool IpVersionRouter::handle(IN const Tins::PDU & pdu, IN IPacketHandler * /* ca
|
||||
const Tins::IPv6 * ipv6Pdu = pdu.find_pdu<Tins::IPv6>();
|
||||
if(ipv6Pdu != nullptr)
|
||||
{
|
||||
ipv6Card->sendPacket(pdu);
|
||||
return true;
|
||||
if (pdu.size() < ipv6Card->getMtu())
|
||||
{
|
||||
ipv6Card->sendPacket(pdu);
|
||||
return true;
|
||||
}
|
||||
|
||||
return ipv6Fragmentation->handle(pdu, this);
|
||||
}
|
||||
|
||||
const Tins::IP * ipv4Pdu = pdu.find_pdu<Tins::IP>();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "AbstractRouter.h"
|
||||
#include "INetworkInterfaceCard_t.h"
|
||||
|
||||
|
||||
class IpVersionRouter: public AbstractRouter
|
||||
{
|
||||
public:
|
||||
@@ -19,6 +20,7 @@ private:
|
||||
|
||||
SPtrINetworkInterfaceCard ipv6Card;
|
||||
SPtrINetworkInterfaceCard ipv4Card;
|
||||
UPtrIPacketHandler ipv6Fragmentation;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTROUTER_H
|
||||
|
||||
@@ -39,6 +39,10 @@ int main(int argc, char** argv)
|
||||
const int itemtype = natPairItem["type"].asInt();
|
||||
const std::string netcardName = natPairItem["nic-name"].asString();
|
||||
SPtrTinsNetworkInterfaceCard netcard = std::make_shared<TinsNetworkInterfaceCard>(netcardName);
|
||||
if(natPairItem.isMember("mtu"))
|
||||
{
|
||||
netcard->setMtu(static_cast<size_t>(natPairItem["mtu"].asInt()));
|
||||
}
|
||||
switch (itemtype)
|
||||
{
|
||||
case 4:
|
||||
|
||||
@@ -33,7 +33,7 @@ TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::IPv6Address & ipv
|
||||
|
||||
}
|
||||
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface) : sniffNetworkInterfaceName(networkInterface.name())
|
||||
TinsNetworkInterfaceCard::TinsNetworkInterfaceCard(const Tins::NetworkInterface & networkInterface) : mtu(DEFAULT_MTU_VAULE), sniffNetworkInterfaceName(networkInterface.name())
|
||||
{
|
||||
snifferConfig = std::make_unique<Tins::SnifferConfiguration>();
|
||||
snifferConfig->set_promisc_mode(true);
|
||||
@@ -111,11 +111,7 @@ void TinsNetworkInterfaceCard::sendPacket(const Tins::PDU &pdu)
|
||||
if (phyLayerLessPdu != nullptr)
|
||||
{
|
||||
addPduToHashList(*phyLayerLessPdu);
|
||||
printf("len: %u, type: %s \n", clonePduRef.size(), typeid(clonePduRef).name());
|
||||
if (clonePduRef.size() < 1500)
|
||||
{
|
||||
packetSender->send(clonePduRef);
|
||||
}
|
||||
packetSender->send(clonePduRef);
|
||||
}
|
||||
|
||||
delete clonePdu;
|
||||
@@ -171,7 +167,12 @@ void TinsNetworkInterfaceCard::stopListen()
|
||||
Tins::EthernetII pkt = Tins::EthernetII();
|
||||
packetSender->send(pkt);
|
||||
std::lock_guard<std::mutex> lockGuard(*hashListMutex);
|
||||
sendPduHashList->clear();
|
||||
sendPduHashList->clear();
|
||||
}
|
||||
|
||||
size_t TinsNetworkInterfaceCard::getMtu() const
|
||||
{
|
||||
return DEFAULT_MTU_VAULE;
|
||||
}
|
||||
|
||||
Tins::PDU * TinsNetworkInterfaceCard::getPhyLessPduPtr(IN Tins::PDU & pdu) const
|
||||
@@ -204,3 +205,8 @@ bool TinsNetworkInterfaceCard::isSniffRunning() const
|
||||
{
|
||||
return isSnifferRunning;
|
||||
}
|
||||
|
||||
void TinsNetworkInterfaceCard::setMtu(const size_t &value)
|
||||
{
|
||||
mtu = value;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <atomic>
|
||||
#include "TinsNetworkInterfaceCard_t.h"
|
||||
#include "INetworkInterfaceCard_t.h"
|
||||
#include "INetworkInterfaceCard.h"
|
||||
#include "Ip4Packet_t.h"
|
||||
#include "Ip6Packet_t.h"
|
||||
@@ -24,14 +23,17 @@ public:
|
||||
virtual void sendPacket(IN const Tins::PDU & pdu) override;
|
||||
virtual void startListen() override;
|
||||
virtual void stopListen() override;
|
||||
virtual size_t getMtu() const override;
|
||||
|
||||
Tins::SnifferConfiguration & getSnifferConfig() const;
|
||||
SPtrIPacketHandlerList & getHandlerList();
|
||||
bool isSniffRunning() const;
|
||||
|
||||
private:
|
||||
void setMtu(const size_t &value);
|
||||
|
||||
bool tinsSnifferCallback(IN Tins::PDU & some_pdu);
|
||||
private:
|
||||
size_t mtu;
|
||||
bool tinsSnifferCallback(IN Tins::PDU & some_pdu);
|
||||
Tins::PDU * getPhyLessPduPtr(IN Tins::PDU & pdu) const;
|
||||
void addPduToHashList(IN Tins::PDU &pdu);
|
||||
bool searchAndRemoveHashListItem(IN const std::size_t removedHash);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <fakeit.hpp>
|
||||
#include <tins/ethernetII.h>
|
||||
#include <tins/ipv6.h>
|
||||
@@ -42,14 +43,15 @@ namespace TestIp6PacketFragmentation
|
||||
|
||||
FragmentionHeaderUnion fragmentionHeaderUnion;
|
||||
FragmentionHeaderStruct * ptrFragmentionHeaderStruct = &fragmentionHeaderUnion.Structed;
|
||||
std::memcpy(&fragmentionHeaderUnion.Bytes[1], fragmentHeader->data_ptr(), fragmentHeader->data_size());
|
||||
std::memcpy(&fragmentionHeaderUnion.Bytes[2], fragmentHeader->data_ptr(), fragmentHeader->data_size());
|
||||
std::swap(fragmentionHeaderUnion.Bytes[2],fragmentionHeaderUnion.Bytes[3]);
|
||||
uint16_t mFlag = fragmentationCount > 1 ? 1 : 0;
|
||||
if (firstFragment)
|
||||
{
|
||||
firstFragment = false;
|
||||
id = ptrFragmentionHeaderStruct->Identification;
|
||||
}
|
||||
REQUIRE(fragmentHeader->option() == Tins::IPv6::FRAGMENT);
|
||||
REQUIRE(fragmentHeader->option() == Tins::Constants::IP::PROTO_TCP);
|
||||
REQUIRE(ptrFragmentionHeaderStruct->Reserved == 0);
|
||||
REQUIRE(ptrFragmentionHeaderStruct->Res == 0);
|
||||
REQUIRE(ptrFragmentionHeaderStruct->MFlag == mFlag);
|
||||
@@ -81,7 +83,7 @@ TEST_CASE( "test Ip6PacketFragmentation", "[Ip6PacketFragmentation]" ) {
|
||||
|
||||
Tins::EthernetII pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / mtuPayload;
|
||||
TestIp6PacketFragmentation::currentInputPdu = &pkt;
|
||||
TestIp6PacketFragmentation::fragmentationCount = 2;
|
||||
TestIp6PacketFragmentation::fragmentationCount = 3;
|
||||
TestIp6PacketFragmentation::maxfragmentationSize = mtu/2;
|
||||
|
||||
REQUIRE(handler.handle(pkt, nullptr) == false);
|
||||
@@ -93,7 +95,7 @@ TEST_CASE( "test Ip6PacketFragmentation", "[Ip6PacketFragmentation]" ) {
|
||||
REQUIRE(handler.handle(pkt, &mockHandler.get()) == false);
|
||||
|
||||
|
||||
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::1", "::2") / mtuPayload;
|
||||
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::1", "::2") / Tins::TCP(1,1) /mtuPayload;
|
||||
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
|
||||
Verify(Method(mockHandler, handle)).Twice();
|
||||
Verify(Method(mockHandler, handle)).Exactly(3);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ TEST_CASE( "test main setup", "[test_main]" )
|
||||
|
||||
SPtrIPacketHandlerList routerList;
|
||||
std::vector<std::thread *> threadPool;
|
||||
int mtuCount = 0;
|
||||
for (Json::Value natpair : natpairs)
|
||||
{
|
||||
const std::string pairname = natpair["name"].asString();
|
||||
@@ -48,6 +49,11 @@ TEST_CASE( "test main setup", "[test_main]" )
|
||||
|
||||
const std::string netcardName = natPairItem["nic-name"].asString();
|
||||
SPtrTinsNetworkInterfaceCard netcard = std::make_shared<TinsNetworkInterfaceCard>(netcardName);
|
||||
if(natPairItem.isMember("mtu"))
|
||||
{
|
||||
mtuCount++;
|
||||
REQUIRE(natPairItem["mtu"].asInt() == 1000);
|
||||
}
|
||||
switch (itemtype)
|
||||
{
|
||||
case 4:
|
||||
@@ -62,6 +68,7 @@ TEST_CASE( "test main setup", "[test_main]" )
|
||||
}
|
||||
}
|
||||
|
||||
REQUIRE(mtuCount ==1);
|
||||
SPtrIPacketHandler ip4ToIp6Handler = std::make_shared<Ip4ToIp6PacketHandler>(prefix);
|
||||
SPtrIPacketHandler ip6ToIp4Handler = std::make_shared<Ip6ToIp4PacketHandler>();
|
||||
SPtrIPacketHandler icmp4ToIcmp6Handler = std::make_shared<Icmp4ToIcmp6PacketHandler>(prefix);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
{
|
||||
"nic-name": "lo",
|
||||
"type": 6,
|
||||
"mtu": 1000,
|
||||
"prefix": "42::"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user