mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added PDUAllocator class, which makes extending PDUs easier.
This commit is contained in:
@@ -110,7 +110,8 @@ libtins_HEADERS = include/internals.h \
|
||||
include/stp.h \
|
||||
include/exceptions.h \
|
||||
include/config.h \
|
||||
include/address_range.h
|
||||
include/address_range.h \
|
||||
include/pdu_allocator.h
|
||||
|
||||
libtins_dot11_HEADERS = include/dot11/dot11_base.h \
|
||||
include/dot11/dot11_beacon.h \
|
||||
|
||||
@@ -397,7 +397,8 @@ libtins_HEADERS = include/internals.h \
|
||||
include/stp.h \
|
||||
include/exceptions.h \
|
||||
include/config.h \
|
||||
include/address_range.h
|
||||
include/address_range.h \
|
||||
include/pdu_allocator.h
|
||||
|
||||
libtins_dot11_HEADERS = include/dot11/dot11_base.h \
|
||||
include/dot11/dot11_beacon.h \
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::IP; }
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
|
||||
182
include/pdu_allocator.h
Normal file
182
include/pdu_allocator.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PDU_ALLOCATOR_H
|
||||
#define TINS_PDU_ALLOCATOR_H
|
||||
|
||||
#include <map>
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
class EthernetII;
|
||||
class SNAP;
|
||||
class Dot1Q;
|
||||
class SLL;
|
||||
class IP;
|
||||
class IPv6;
|
||||
|
||||
namespace Internals {
|
||||
template<typename PDUType>
|
||||
PDU *default_allocator(const uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
return new PDUType(buffer, size);
|
||||
}
|
||||
|
||||
template<typename Tag>
|
||||
class PDUAllocator {
|
||||
public:
|
||||
typedef typename Tag::identifier_type id_type;
|
||||
typedef PDU *(*allocator_type)(const uint8_t *, uint32_t);
|
||||
|
||||
template<typename PDUType>
|
||||
static void register_allocator(id_type identifier)
|
||||
{
|
||||
allocators[identifier] = &default_allocator<PDUType>;
|
||||
pdu_types[PDUType::pdu_flag] = identifier;
|
||||
}
|
||||
|
||||
static PDU *allocate(id_type identifier, const uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
typename allocators_type::const_iterator it = allocators.find(identifier);
|
||||
return (it == allocators.end()) ? 0 : (*it->second)(buffer, size);
|
||||
}
|
||||
|
||||
static bool pdu_type_registered(PDU::PDUType type)
|
||||
{
|
||||
return pdu_types.count(type) != 0;
|
||||
}
|
||||
|
||||
static id_type pdu_type_to_id(PDU::PDUType type)
|
||||
{
|
||||
typename pdu_map_types::const_iterator it = pdu_types.find(type);
|
||||
return it->second;
|
||||
}
|
||||
private:
|
||||
typedef std::map<id_type, allocator_type> allocators_type;
|
||||
typedef std::map<PDU::PDUType, id_type> pdu_map_types;
|
||||
|
||||
static allocators_type allocators;
|
||||
static pdu_map_types pdu_types;
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
typename PDUAllocator<Tag>::allocators_type PDUAllocator<Tag>::allocators;
|
||||
|
||||
template<typename Tag>
|
||||
typename PDUAllocator<Tag>::pdu_map_types PDUAllocator<Tag>::pdu_types;
|
||||
|
||||
template<typename IDType>
|
||||
struct pdu_tag {
|
||||
typedef IDType identifier_type;
|
||||
};
|
||||
|
||||
template<typename PDUType>
|
||||
struct pdu_tag_mapper;
|
||||
|
||||
#define TINS_GENERATE_TAG_MAPPER(pdu, id_type) \
|
||||
template<> \
|
||||
struct pdu_tag_mapper<pdu> { \
|
||||
typedef pdu_tag<id_type> type; \
|
||||
};
|
||||
|
||||
TINS_GENERATE_TAG_MAPPER(EthernetII, uint16_t)
|
||||
TINS_GENERATE_TAG_MAPPER(SNAP, uint16_t)
|
||||
TINS_GENERATE_TAG_MAPPER(SLL, uint16_t)
|
||||
TINS_GENERATE_TAG_MAPPER(Dot1Q, uint16_t)
|
||||
TINS_GENERATE_TAG_MAPPER(IP, uint8_t)
|
||||
TINS_GENERATE_TAG_MAPPER(IPv6, uint8_t)
|
||||
|
||||
#undef TINS_GENERATE_TAG_MAPPER
|
||||
|
||||
template<typename PDUType>
|
||||
PDU* allocate(
|
||||
typename pdu_tag_mapper<PDUType>::type::identifier_type id,
|
||||
const uint8_t *buffer,
|
||||
uint32_t size)
|
||||
{
|
||||
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::allocate(id, buffer, size);
|
||||
}
|
||||
|
||||
template<typename PDUType>
|
||||
bool pdu_type_registered(PDU::PDUType type)
|
||||
{
|
||||
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_registered(type);
|
||||
}
|
||||
|
||||
template<typename PDUType>
|
||||
typename pdu_tag_mapper<PDUType>::type::identifier_type pdu_type_to_id(PDU::PDUType type)
|
||||
{
|
||||
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_to_id(type);
|
||||
}
|
||||
} // namespace Interals
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Defines inner PDU allocators.
|
||||
*/
|
||||
namespace Allocators {
|
||||
/**
|
||||
* \brief Registers an allocator for the provided PDU type.
|
||||
*
|
||||
* Registering a certain allocator for a PDU type is useful for
|
||||
* extending the library. Once an allocator is registered, it will
|
||||
* be taken into account while constructing a PDU from a buffer.
|
||||
*
|
||||
* If PDU finds that it cannot define which is the protocol
|
||||
* that should be allocated based on its protocol identifier, it
|
||||
* will try using the registered allocators if any.
|
||||
*
|
||||
* \code
|
||||
* // Register the 0x666 identifer. Now if EthernetII finds a
|
||||
* // network layer identifier field whose value is 0x666, it will
|
||||
* // use SomePDUType as its inner PDU type.
|
||||
* Allocators::register_allocator<EthernetII, SomePDUType>(0x666);
|
||||
* \endcode
|
||||
*
|
||||
* Note that some PDU types are grouped together. For example,
|
||||
* registering an allocator for EthernetII will make it work for
|
||||
* the rest of the link layer protocols, sine they should all work
|
||||
* the same way.
|
||||
*/
|
||||
template<typename PDUType, typename AllocatedType>
|
||||
void register_allocator(typename Internals::pdu_tag_mapper<PDUType>::type::identifier_type id)
|
||||
{
|
||||
Internals::PDUAllocator<
|
||||
typename Internals::pdu_tag_mapper<PDUType>::type
|
||||
>::template register_allocator<AllocatedType>(id);
|
||||
}
|
||||
} // namespace Allocators
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_PDU_ALLOCATOR_H
|
||||
@@ -69,5 +69,6 @@
|
||||
#include "stp.h"
|
||||
#include "handshake_capturer.h"
|
||||
#include "address_range.h"
|
||||
#include "pdu_allocator.h"
|
||||
|
||||
#endif // TINS_TINS_H
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "pppoe.h"
|
||||
#include "ip_address.h"
|
||||
#include "ipv6_address.h"
|
||||
#include "pdu_allocator.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@@ -74,18 +75,27 @@ Tins::PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
|
||||
{
|
||||
switch(flag) {
|
||||
case Tins::Constants::Ethernet::IP:
|
||||
return new Tins::IP(buffer, size);
|
||||
return new IP(buffer, size);
|
||||
case Constants::Ethernet::IPV6:
|
||||
return new Tins::IPv6(buffer, size);
|
||||
return new IPv6(buffer, size);
|
||||
case Tins::Constants::Ethernet::ARP:
|
||||
return new Tins::ARP(buffer, size);
|
||||
return new ARP(buffer, size);
|
||||
case Tins::Constants::Ethernet::PPPOED:
|
||||
return new Tins::PPPoE(buffer, size);
|
||||
return new PPPoE(buffer, size);
|
||||
case Tins::Constants::Ethernet::EAPOL:
|
||||
return Tins::EAPOL::from_bytes(buffer, size);
|
||||
return EAPOL::from_bytes(buffer, size);
|
||||
case Tins::Constants::Ethernet::VLAN:
|
||||
return new Tins::Dot1Q(buffer, size);
|
||||
return new Dot1Q(buffer, size);
|
||||
default:
|
||||
{
|
||||
PDU *pdu = Internals::allocate<EthernetII>(
|
||||
static_cast<uint16_t>(flag),
|
||||
buffer,
|
||||
size
|
||||
);
|
||||
if(pdu)
|
||||
return pdu;
|
||||
}
|
||||
return rawpdu_on_no_match ? new RawPDU(buffer, size) : 0;
|
||||
};
|
||||
}
|
||||
@@ -148,6 +158,10 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
|
||||
case PDU::PPPOE:
|
||||
return Constants::Ethernet::PPPOED;
|
||||
default:
|
||||
if(Internals::pdu_type_registered<EthernetII>(flag))
|
||||
return static_cast<Constants::Ethernet::e>(
|
||||
Internals::pdu_type_to_id<EthernetII>(flag)
|
||||
);
|
||||
return Constants::Ethernet::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
20
src/ip.cpp
20
src/ip.cpp
@@ -52,6 +52,7 @@
|
||||
#include "constants.h"
|
||||
#include "network_interface.h"
|
||||
#include "exceptions.h"
|
||||
#include "pdu_allocator.h"
|
||||
|
||||
using std::list;
|
||||
|
||||
@@ -134,7 +135,15 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
inner_pdu(new Tins::IPv6(buffer, total_sz));
|
||||
break;
|
||||
default:
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
inner_pdu(
|
||||
Internals::allocate<IP>(
|
||||
_ip.protocol,
|
||||
buffer,
|
||||
total_sz
|
||||
)
|
||||
);
|
||||
if(!inner_pdu())
|
||||
inner_pdu(new RawPDU(buffer, total_sz));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -397,8 +406,13 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
|
||||
new_flag = Constants::IP::PROTO_ICMP;
|
||||
break;
|
||||
default:
|
||||
// check for other protos
|
||||
new_flag = 0xff;
|
||||
if(Internals::pdu_type_registered<IP>(inner_pdu()->pdu_type()))
|
||||
new_flag = static_cast<Constants::IP::e>(
|
||||
Internals::pdu_type_to_id<IP>(inner_pdu()->pdu_type())
|
||||
);
|
||||
else
|
||||
// check for other protos
|
||||
new_flag = 0xff;
|
||||
};
|
||||
protocol(new_flag);
|
||||
//flag(new_flag);
|
||||
|
||||
18
src/ipv6.cpp
18
src/ipv6.cpp
@@ -48,6 +48,7 @@
|
||||
#include "icmpv6.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
#include "pdu_allocator.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -101,7 +102,15 @@ IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
inner_pdu(new Tins::ICMPv6(buffer, total_sz));
|
||||
break;
|
||||
default:
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
inner_pdu(
|
||||
Internals::allocate<IPv6>(
|
||||
current_header,
|
||||
buffer,
|
||||
total_sz
|
||||
)
|
||||
);
|
||||
if(!inner_pdu())
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
break;
|
||||
}
|
||||
total_sz = 0;
|
||||
@@ -214,10 +223,13 @@ void IPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
|
||||
new_flag = Constants::IP::PROTO_ICMPV6;
|
||||
break;
|
||||
default:
|
||||
if(Internals::pdu_type_registered<IPv6>(inner_pdu()->pdu_type()))
|
||||
new_flag = static_cast<Constants::IP::e>(
|
||||
Internals::pdu_type_to_id<IPv6>(inner_pdu()->pdu_type())
|
||||
);
|
||||
break;
|
||||
};
|
||||
if(new_flag != 0xff)
|
||||
set_last_next_header(new_flag);
|
||||
set_last_next_header(new_flag);
|
||||
}
|
||||
payload_length(total_sz - sizeof(_header));
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
|
||||
@@ -874,7 +874,8 @@
|
||||
../include/dot11/../cxxstd.h ../include/dot11/../macros.h \
|
||||
../include/ipv6.h ../include/ipv6_address.h ../include/arp.h \
|
||||
../include/eapol.h ../include/rawpdu.h ../include/dot1q.h \
|
||||
../include/pppoe.h ../include/ip_address.h ../include/ipv6_address.h
|
||||
../include/pppoe.h ../include/ip_address.h ../include/ipv6_address.h \
|
||||
../include/pdu_allocator.h
|
||||
|
||||
../include/internals.h:
|
||||
|
||||
@@ -941,6 +942,8 @@
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/ipv6_address.h:
|
||||
|
||||
../include/pdu_allocator.h:
|
||||
../src/ip.o: ../src/ip.cpp ../include/ip.h ../include/pdu.h \
|
||||
../include/macros.h ../include/cxxstd.h ../include/exceptions.h \
|
||||
../include/small_uint.h ../include/endianness.h ../include/ip_address.h \
|
||||
@@ -949,7 +952,8 @@
|
||||
../include/utils.h ../include/hw_address.h ../include/internals.h \
|
||||
../include/constants.h ../include/packet_sender.h \
|
||||
../include/network_interface.h ../include/constants.h \
|
||||
../include/network_interface.h ../include/exceptions.h
|
||||
../include/network_interface.h ../include/exceptions.h \
|
||||
../include/pdu_allocator.h
|
||||
|
||||
../include/ip.h:
|
||||
|
||||
@@ -998,6 +1002,8 @@
|
||||
../include/network_interface.h:
|
||||
|
||||
../include/exceptions.h:
|
||||
|
||||
../include/pdu_allocator.h:
|
||||
../src/ip_address.o: ../src/ip_address.cpp ../include/ip_address.h \
|
||||
../include/cxxstd.h ../include/endianness.h ../include/macros.h \
|
||||
../include/address_range.h ../include/ip_address.h \
|
||||
@@ -1034,7 +1040,7 @@
|
||||
../include/packet_sender.h ../include/network_interface.h \
|
||||
../include/hw_address.h ../include/ip_address.h ../include/ip.h \
|
||||
../include/tcp.h ../include/udp.h ../include/icmp.h ../include/icmpv6.h \
|
||||
../include/rawpdu.h ../include/exceptions.h
|
||||
../include/rawpdu.h ../include/exceptions.h ../include/pdu_allocator.h
|
||||
|
||||
../include/ipv6.h:
|
||||
|
||||
@@ -1077,14 +1083,37 @@
|
||||
../include/rawpdu.h:
|
||||
|
||||
../include/exceptions.h:
|
||||
|
||||
../include/pdu_allocator.h:
|
||||
../src/ipv6_address.o: ../src/ipv6_address.cpp ../include/macros.h \
|
||||
../include/ipv6_address.h ../include/cxxstd.h
|
||||
../include/ipv6_address.h ../include/cxxstd.h ../include/address_range.h \
|
||||
../include/ip_address.h ../include/ipv6_address.h \
|
||||
../include/endianness.h ../include/macros.h ../include/internals.h \
|
||||
../include/constants.h ../include/pdu.h ../include/exceptions.h
|
||||
|
||||
../include/macros.h:
|
||||
|
||||
../include/ipv6_address.h:
|
||||
|
||||
../include/cxxstd.h:
|
||||
|
||||
../include/address_range.h:
|
||||
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/ipv6_address.h:
|
||||
|
||||
../include/endianness.h:
|
||||
|
||||
../include/macros.h:
|
||||
|
||||
../include/internals.h:
|
||||
|
||||
../include/constants.h:
|
||||
|
||||
../include/pdu.h:
|
||||
|
||||
../include/exceptions.h:
|
||||
../src/llc.o: ../src/llc.cpp ../include/llc.h ../include/macros.h \
|
||||
../include/pdu.h ../include/cxxstd.h ../include/exceptions.h \
|
||||
../include/endianness.h ../include/stp.h ../include/hw_address.h \
|
||||
@@ -1800,6 +1829,47 @@ src/address_range.o: src/address_range.cpp ../include/address_range.h \
|
||||
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/ipv6_address.h:
|
||||
src/allocators.o: src/allocators.cpp ../include/pdu_allocator.h \
|
||||
../include/pdu.h ../include/macros.h ../include/cxxstd.h \
|
||||
../include/exceptions.h ../include/ethernetII.h ../include/endianness.h \
|
||||
../include/hw_address.h ../include/snap.h ../include/small_uint.h \
|
||||
../include/sll.h ../include/dot1q.h ../include/ip.h \
|
||||
../include/ip_address.h ../include/pdu_option.h ../include/ipv6.h \
|
||||
../include/ipv6_address.h
|
||||
|
||||
../include/pdu_allocator.h:
|
||||
|
||||
../include/pdu.h:
|
||||
|
||||
../include/macros.h:
|
||||
|
||||
../include/cxxstd.h:
|
||||
|
||||
../include/exceptions.h:
|
||||
|
||||
../include/ethernetII.h:
|
||||
|
||||
../include/endianness.h:
|
||||
|
||||
../include/hw_address.h:
|
||||
|
||||
../include/snap.h:
|
||||
|
||||
../include/small_uint.h:
|
||||
|
||||
../include/sll.h:
|
||||
|
||||
../include/dot1q.h:
|
||||
|
||||
../include/ip.h:
|
||||
|
||||
../include/ip_address.h:
|
||||
|
||||
../include/pdu_option.h:
|
||||
|
||||
../include/ipv6.h:
|
||||
|
||||
../include/ipv6_address.h:
|
||||
src/arp.o: src/arp.cpp ../include/arp.h ../include/macros.h \
|
||||
../include/pdu.h ../include/cxxstd.h ../include/exceptions.h \
|
||||
@@ -2778,7 +2848,7 @@ src/ethernetII.o: src/ethernetII.cpp ../include/ethernetII.h \
|
||||
../include/utils.h ../include/ip_address.h ../include/ipv6_address.h \
|
||||
../include/internals.h ../include/constants.h ../include/macros.h \
|
||||
../include/ipv6.h ../include/small_uint.h ../include/pdu_option.h \
|
||||
../include/ip.h
|
||||
../include/ip.h ../include/tcp.h ../include/rawpdu.h
|
||||
|
||||
../include/ethernetII.h:
|
||||
|
||||
@@ -2813,6 +2883,10 @@ src/ethernetII.o: src/ethernetII.cpp ../include/ethernetII.h \
|
||||
../include/pdu_option.h:
|
||||
|
||||
../include/ip.h:
|
||||
|
||||
../include/tcp.h:
|
||||
|
||||
../include/rawpdu.h:
|
||||
src/hwaddress.o: src/hwaddress.cpp ../include/hw_address.h \
|
||||
../include/cxxstd.h
|
||||
|
||||
|
||||
119
tests/src/allocators.cpp
Normal file
119
tests/src/allocators.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include "pdu_allocator.h"
|
||||
#include "ethernetII.h"
|
||||
#include "snap.h"
|
||||
#include "sll.h"
|
||||
#include "dot1q.h"
|
||||
#include "ip.h"
|
||||
#include "ipv6.h"
|
||||
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class AllocatorsTest : public testing::Test {
|
||||
public:
|
||||
static const uint8_t link_layer_data_buffer[], ipv4_data_buffer[], ipv6_data_buffer[];
|
||||
};
|
||||
|
||||
const uint8_t AllocatorsTest::link_layer_data_buffer[] = {
|
||||
0, 27, 17, 210, 243, 22, 0, 25, 209, 22, 248, 43, 6, 102, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65
|
||||
};
|
||||
|
||||
const uint8_t AllocatorsTest::ipv4_data_buffer[] = {
|
||||
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 8, 0, 69, 0, 0, 60,
|
||||
0, 1, 0, 0, 64, 255, 123, 192, 127, 0, 0, 1, 127, 0, 0, 1, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65
|
||||
};
|
||||
|
||||
const uint8_t AllocatorsTest::ipv6_data_buffer[] = {
|
||||
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 134, 221, 96, 0, 0,
|
||||
0, 0, 40, 250, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65
|
||||
};
|
||||
|
||||
class DummyPDU : public PDU {
|
||||
public:
|
||||
static const PDU::PDUType pdu_flag;
|
||||
|
||||
DummyPDU(const uint8_t* data, uint32_t sz) : buffer(data, data + sz) { }
|
||||
DummyPDU *clone() const { return new DummyPDU(*this); }
|
||||
uint32_t header_size() const { return buffer.size(); }
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
void write_serialization(uint8_t *data, uint32_t, const PDU *)
|
||||
{
|
||||
std::copy(buffer.begin(), buffer.end(), data);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> buffer;
|
||||
};
|
||||
|
||||
const PDU::PDUType DummyPDU::pdu_flag = static_cast<PDU::PDUType>(0xefff);
|
||||
|
||||
TEST_F(AllocatorsTest, LinkLayerPDUs) {
|
||||
Allocators::register_allocator<EthernetII, DummyPDU>(1638);
|
||||
Allocators::register_allocator<SNAP, DummyPDU>(25);
|
||||
Allocators::register_allocator<Dot1Q, DummyPDU>(4562);
|
||||
Allocators::register_allocator<SLL, DummyPDU>(16705);
|
||||
std::vector<uint8_t> link_layer_data(
|
||||
link_layer_data_buffer,
|
||||
link_layer_data_buffer + sizeof(link_layer_data_buffer)
|
||||
);
|
||||
{
|
||||
EthernetII pkt(&link_layer_data[0], link_layer_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), link_layer_data);
|
||||
}
|
||||
{
|
||||
SNAP pkt(&link_layer_data[0], link_layer_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), link_layer_data);
|
||||
}
|
||||
{
|
||||
SLL pkt(&link_layer_data[0], link_layer_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), link_layer_data);
|
||||
}
|
||||
{
|
||||
Dot1Q pkt(&link_layer_data[0], link_layer_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), link_layer_data);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTest, IP) {
|
||||
std::vector<uint8_t> ipv4_data(
|
||||
ipv4_data_buffer,
|
||||
ipv4_data_buffer + sizeof(ipv4_data_buffer)
|
||||
);
|
||||
Allocators::register_allocator<IP, DummyPDU>(255);
|
||||
EthernetII pkt(&ipv4_data[0], ipv4_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<IP>());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), ipv4_data);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTest, IPv6) {
|
||||
std::vector<uint8_t> ipv6_data(
|
||||
ipv6_data_buffer,
|
||||
ipv6_data_buffer + sizeof(ipv6_data_buffer)
|
||||
);
|
||||
Allocators::register_allocator<IPv6, DummyPDU>(250);
|
||||
{
|
||||
EthernetII pkt(&ipv6_data[0], ipv6_data.size());
|
||||
EXPECT_TRUE(pkt.find_pdu<IPv6>());
|
||||
EXPECT_TRUE(pkt.find_pdu<DummyPDU>());
|
||||
EXPECT_EQ(pkt.serialize(), ipv6_data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user