libtins 4.5
Loading...
Searching...
No Matches
pdu_allocator.h
1/*
2 * Copyright (c) 2017, Matias Fontanini
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef TINS_PDU_ALLOCATOR_H
31#define TINS_PDU_ALLOCATOR_H
32
33#include <map>
34#include <tins/pdu.h>
35
36namespace Tins {
40class EthernetII;
41class SNAP;
42class Dot1Q;
43class SLL;
44class IP;
45class IPv6;
46
47namespace Internals {
48
49template<typename PDUType>
50PDU* default_allocator(const uint8_t* buffer, uint32_t size) {
51 return new PDUType(buffer, size);
52}
53
54template<typename Tag>
55class PDUAllocator {
56public:
57 typedef typename Tag::identifier_type id_type;
58 typedef PDU *(*allocator_type)(const uint8_t *, uint32_t);
59
60 template<typename PDUType>
61 static void register_allocator(id_type identifier) {
62 allocators[identifier] = &default_allocator<PDUType>;
63 pdu_types[PDUType::pdu_flag] = identifier;
64 }
65
66 static PDU* allocate(id_type identifier, const uint8_t* buffer, uint32_t size) {
67 typename allocators_type::const_iterator it = allocators.find(identifier);
68 return (it == allocators.end()) ? 0 : (*it->second)(buffer, size);
69 }
70
71 static bool pdu_type_registered(PDU::PDUType type) {
72 return pdu_types.count(type) != 0;
73 }
74
75 static id_type pdu_type_to_id(PDU::PDUType type) {
76 typename pdu_map_types::const_iterator it = pdu_types.find(type);
77 return it->second;
78 }
79private:
80 typedef std::map<id_type, allocator_type> allocators_type;
81 typedef std::map<PDU::PDUType, id_type> pdu_map_types;
82
83 static allocators_type allocators;
84 static pdu_map_types pdu_types;
85};
86
87template<typename Tag>
88typename PDUAllocator<Tag>::allocators_type PDUAllocator<Tag>::allocators;
89
90template<typename Tag>
91typename PDUAllocator<Tag>::pdu_map_types PDUAllocator<Tag>::pdu_types;
92
93template<typename IDType>
94struct pdu_tag {
95 typedef IDType identifier_type;
96};
97
98template<typename PDUType>
99struct pdu_tag_mapper;
100
101#define TINS_GENERATE_TAG_MAPPER(pdu, id_type) \
102template<> \
103struct pdu_tag_mapper<pdu> { \
104 typedef pdu_tag<id_type> type; \
105};
106
107TINS_GENERATE_TAG_MAPPER(EthernetII, uint16_t)
108TINS_GENERATE_TAG_MAPPER(SNAP, uint16_t)
109TINS_GENERATE_TAG_MAPPER(SLL, uint16_t)
110TINS_GENERATE_TAG_MAPPER(Dot1Q, uint16_t)
111TINS_GENERATE_TAG_MAPPER(IP, uint8_t)
112TINS_GENERATE_TAG_MAPPER(IPv6, uint8_t)
113
114#undef TINS_GENERATE_TAG_MAPPER
115
116template<typename PDUType>
117PDU* allocate(typename pdu_tag_mapper<PDUType>::type::identifier_type id,
118 const uint8_t* buffer,
119 uint32_t size) {
120 return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::allocate(id, buffer, size);
121}
122
123template<typename PDUType>
124bool pdu_type_registered(PDU::PDUType type) {
125 return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_registered(type);
126}
127
128template<typename PDUType>
129typename pdu_tag_mapper<PDUType>::type::identifier_type pdu_type_to_id(PDU::PDUType type) {
130 return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_to_id(type);
131}
132
133} // Interals
141namespace Allocators {
165template<typename PDUType, typename AllocatedType>
166void register_allocator(typename Internals::pdu_tag_mapper<PDUType>::type::identifier_type id) {
167 Internals::PDUAllocator<
168 typename Internals::pdu_tag_mapper<PDUType>::type
169 >::template register_allocator<AllocatedType>(id);
170}
171
172} // Allocators
173} // Tins
174
175#endif // TINS_PDU_ALLOCATOR_H
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
void register_allocator(typename Internals::pdu_tag_mapper< PDUType >::type::identifier_type id)
Registers an allocator for the provided PDU type.
Definition pdu_allocator.h:166
The Tins namespace.
Definition address_range.h:38