add ip fragmentation test and fixes

This commit is contained in:
stubbfel
2017-06-14 23:53:45 +02:00
parent 1345a8013c
commit 5185c025d8
6 changed files with 133 additions and 29 deletions

View File

@@ -0,0 +1,99 @@
#include <fakeit.hpp>
#include <tins/ethernetII.h>
#include <tins/ipv6.h>
#include <tins/ipv6_address.h>
#include <tins/tcp.h>
#include <tins/rawpdu.h>
#include "IpPacketFragmentation.h"
using namespace fakeit;
namespace TestIp6PacketFragmentation
{
static Tins::PDU * currentInputPdu = nullptr;
static size_t fragmentationCount = 0;
static long maxfragmentationSize = 0;
static bool firstFragment = true;
static uint32_t id = -1;
void compareToInputPdu(const Tins::PDU & answerPdu)
{
const Tins::IPv6 * ipPdu = answerPdu.find_pdu<Tins::IPv6>();
if (ipPdu == nullptr)
{
FAIL("got no ip6 packet");
}
Tins::PDU * ipDataPdu = ipPdu->inner_pdu();
if (ipDataPdu == nullptr)
{
FAIL("got no ip6 inner pdu");
}
const long ipPayloadSize = static_cast<const long>(ipDataPdu->size());
REQUIRE(ipPayloadSize <= maxfragmentationSize);
REQUIRE(ipPayloadSize > 0);
const Tins::IPv6::ext_header * fragmentHeader = ipPdu->search_header(Tins::IPv6::FRAGMENT);
if (fragmentHeader == nullptr)
{
FAIL("got no fragment header");
}
FragmentionHeaderUnion fragmentionHeaderUnion;
FragmentionHeaderStruct * ptrFragmentionHeaderStruct = &fragmentionHeaderUnion.Structed;
std::memcpy(&fragmentionHeaderUnion.Bytes[1], fragmentHeader->data_ptr(), fragmentHeader->data_size());
uint16_t mFlag = fragmentationCount > 1 ? 1 : 0;
if (firstFragment)
{
firstFragment = false;
id = ptrFragmentionHeaderStruct->Identification;
}
REQUIRE(fragmentHeader->option() == Tins::IPv6::FRAGMENT);
REQUIRE(ptrFragmentionHeaderStruct->Reserved == 0);
REQUIRE(ptrFragmentionHeaderStruct->Res == 0);
REQUIRE(ptrFragmentionHeaderStruct->MFlag == mFlag);
REQUIRE(ptrFragmentionHeaderStruct->Identification == id);
fragmentationCount--;
}
}
#ifndef TEST_MTU
#define TEST_MTU 1500
#endif
TEST_CASE( "test Ip6PacketFragmentation", "[Ip6PacketFragmentation]" ) {
const size_t mtu = TEST_MTU;
ByteVector mtu_Payload;
for (size_t i = 0; i < mtu; i++)
{
mtu_Payload.push_back(0);
}
Tins::RawPDU mtuPayload(mtu_Payload.data(), mtu);
IpPacketFragmentation handler(1500);
Mock<IPacketHandler> mockHandler;
When(Method(mockHandler, handle)).AlwaysDo([] (IN const Tins::PDU & pdu,...)
{
TestIp6PacketFragmentation::compareToInputPdu(pdu);
return true;
});
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::maxfragmentationSize = mtu/2;
REQUIRE(handler.handle(pkt, nullptr) == false);
Verify(Method(mockHandler, handle)).Never();
REQUIRE(handler.handle(pkt, &mockHandler.get()) == false);
Verify(Method(mockHandler, handle)).Never();
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / mtuPayload / Tins::IPv6("::1", "::2");
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;
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Twice();
}

View File

@@ -44,17 +44,17 @@ namespace TestIp6ToIp4PacketHandler
}
TEST_CASE( "test Ip6ToIp4PacketHandler", "[Ip6ToIp4PacketHandler]" ) {
Ip6ToIp4PacketHandler handler;
Ip6ToIp4PacketHandler handler;
Mock<IPacketHandler> mockHandler;
When(Method(mockHandler, handle)).AlwaysDo([] (IN const Tins::PDU & pdu,...)
{
TestIp6ToIp4PacketHandler::compareToInputPdu(pdu);
TestIp6ToIp4PacketHandler::compareToInputPdu(pdu);
return true;
});
Tins::IPv6 tmpPkt = Tins::IPv6() / Tins::TCP();
Tins::EthernetII pkt = Tins::EthernetII() / tmpPkt;
TestIp6ToIp4PacketHandler::currentInputPdu = &pkt;
TestIp6ToIp4PacketHandler::currentInputPdu = &pkt;
REQUIRE(handler.handle(pkt, nullptr) == false);
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Once();
@@ -63,21 +63,21 @@ TEST_CASE( "test Ip6ToIp4PacketHandler", "[Ip6ToIp4PacketHandler]" ) {
REQUIRE(handler.handle(pkt, &mockHandler.get()) == true);
Verify(Method(mockHandler, handle)).Twice();
// test pkt hashes
Tins::EthernetII * clonePkt = pkt.clone();
REQUIRE((long) clonePkt != (long) &pkt);
Tins::PDU::serialization_type ser_pkt = pkt.serialize();
Tins::PDU::serialization_type ser_clonepkt = clonePkt->serialize();
REQUIRE(ser_pkt == ser_clonepkt);
// test pkt hashes
Tins::EthernetII * clonePkt = pkt.clone();
REQUIRE((long) clonePkt != (long) &pkt);
Tins::PDU::serialization_type ser_pkt = pkt.serialize();
Tins::PDU::serialization_type ser_clonepkt = clonePkt->serialize();
REQUIRE(ser_pkt == ser_clonepkt);
Tins::PDU & pdu = *((Tins::PDU *)&pkt);
std::hash<Tins::PDU::serialization_type>pdu_hash;
std::size_t h1 = pdu_hash(ser_pkt);
std::size_t h2 = pdu_hash(ser_clonepkt);
Tins::PDU & pdu = *((Tins::PDU *)&pkt);
std::hash<Tins::PDU::serialization_type>pdu_hash;
std::size_t h1 = pdu_hash(ser_pkt);
std::size_t h2 = pdu_hash(ser_clonepkt);
REQUIRE(h1 == h2);
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::2", "::1") / Tins::TCP();
ser_pkt = pkt.serialize();
h1 = pdu_hash(ser_pkt);
REQUIRE(h1 != h2);
REQUIRE(h1 == h2);
pkt = Tins::EthernetII("11:22:33:44:55:66", "66:55:44:33:22:11") / Tins::IPv6("::2", "::1") / Tins::TCP();
ser_pkt = pkt.serialize();
h1 = pdu_hash(ser_pkt);
REQUIRE(h1 != h2);
}