finish ipv6 fragmentation
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user