libtins 4.6
Loading...
Searching...
No Matches
pdu.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_H
31#define TINS_PDU_H
32
33
34#include <stdint.h>
35#include <vector>
36#include <tins/macros.h>
37#include <tins/cxxstd.h>
38#include <tins/exceptions.h>
39
42namespace Tins {
43
44class PacketSender;
46
50typedef std::vector<uint8_t> byte_array;
51
107class TINS_API PDU {
108public:
113
118 BE,
119 LE
120 };
121
127 enum PDUType {
128 RAW,
129 ETHERNET_II,
130 IEEE802_3,
131 DOT3 = IEEE802_3,
132 RADIOTAP,
133 DOT11,
134 DOT11_ACK,
135 DOT11_ASSOC_REQ,
136 DOT11_ASSOC_RESP,
137 DOT11_AUTH,
138 DOT11_BEACON,
139 DOT11_BLOCK_ACK,
140 DOT11_BLOCK_ACK_REQ,
141 DOT11_CF_END,
142 DOT11_DATA,
143 DOT11_CONTROL,
144 DOT11_DEAUTH,
145 DOT11_DIASSOC,
146 DOT11_END_CF_ACK,
147 DOT11_MANAGEMENT,
148 DOT11_PROBE_REQ,
149 DOT11_PROBE_RESP,
150 DOT11_PS_POLL,
151 DOT11_REASSOC_REQ,
152 DOT11_REASSOC_RESP,
153 DOT11_RTS,
154 DOT11_QOS_DATA,
155 LLC,
156 SNAP,
157 IP,
158 ARP,
159 TCP,
160 UDP,
161 ICMP,
162 BOOTP,
163 DHCP,
164 EAPOL,
165 RC4EAPOL,
166 RSNEAPOL,
167 DNS,
168 LOOPBACK,
169 IPv6,
170 ICMPv6,
171 SLL,
172 DHCPv6,
173 DOT1AD,
174 DOT1Q,
175 PPPOE,
176 STP,
177 PPI,
178 IPSEC_AH,
179 IPSEC_ESP,
180 PKTAP,
181 MPLS,
182 DOT11_CONTROL_TA,
183 VXLAN,
184 RTP,
185 UNKNOWN = 999,
186 USER_DEFINED_PDU = 1000
187 };
188
193 static const endian_type endianness = BE;
194
198 struct metadata {
202 metadata();
203
208 metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
209
213 uint32_t header_size;
214
219
224 };
225
229 PDU();
230
231 #if TINS_IS_CXX11
237 PDU(PDU &&rhs) TINS_NOEXCEPT
238 : inner_pdu_(0), parent_pdu_(0) {
239 std::swap(inner_pdu_, rhs.inner_pdu_);
240 if (inner_pdu_) {
241 inner_pdu_->parent_pdu(this);
242 }
243 }
244
250 PDU& operator=(PDU &&rhs) TINS_NOEXCEPT {
251 delete inner_pdu_;
252 inner_pdu_ = 0;
253 std::swap(inner_pdu_, rhs.inner_pdu_);
254 if (inner_pdu_) {
255 inner_pdu_->parent_pdu(this);
256 }
257 return* this;
258 }
259 #endif
260
267 virtual ~PDU();
268
271 virtual uint32_t header_size() const = 0;
272
277 virtual uint32_t trailer_size() const {
278 return 0;
279 }
280
285 uint32_t size() const;
286
291 virtual uint32_t advertised_size() const;
292
297 PDU* inner_pdu() const {
298 return inner_pdu_;
299 }
300
305 PDU* parent_pdu() const {
306 return parent_pdu_;
307 }
308
322 PDU* release_inner_pdu();
323
332 void inner_pdu(PDU* next_pdu);
333
341 void inner_pdu(const PDU& next_pdu);
342
352 serialization_type serialize();
353
362 template<typename T>
363 T* find_pdu(PDUType type = T::pdu_flag) {
364 PDU* pdu = this;
365 while (pdu) {
366 if (pdu->matches_flag(type)) {
367 return static_cast<T*>(pdu);
368 }
369 pdu = pdu->inner_pdu();
370 }
371 return 0;
372 }
373
379 template<typename T>
380 const T* find_pdu(PDUType type = T::pdu_flag) const {
381 return const_cast<PDU*>(this)->find_pdu<T>(type);
382 }
383
393 template<typename T>
394 T& rfind_pdu(PDUType type = T::pdu_flag) {
395 T* ptr = find_pdu<T>(type);
396 if (!ptr) {
397 throw pdu_not_found();
398 }
399 return* ptr;
400 }
401
407 template<typename T>
408 const T& rfind_pdu(PDUType type = T::pdu_flag) const {
409 return const_cast<PDU*>(this)->rfind_pdu<T>(type);
410 }
411
420 virtual PDU* clone() const = 0;
421
439 virtual void send(PacketSender& sender, const NetworkInterface& iface);
440
449 virtual PDU* recv_response(PacketSender& sender, const NetworkInterface& iface);
450
461 virtual bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
462
471 virtual bool matches_flag(PDUType flag) const {
472 return flag == pdu_type();
473 }
474
480 virtual PDUType pdu_type() const = 0;
481protected:
485 PDU(const PDU& other);
486
490 PDU& operator=(const PDU& other);
491
496 void copy_inner_pdu(const PDU& pdu);
497
509 virtual void prepare_for_serialize();
510
517 void serialize(uint8_t* buffer, uint32_t total_sz);
518
527 virtual void write_serialization(uint8_t* buffer, uint32_t total_sz) = 0;
528private:
529 void parent_pdu(PDU* parent);
530
531 PDU* inner_pdu_;
532 PDU* parent_pdu_;
533};
534
553template<typename T>
554T& operator/= (T& lop, const PDU& rop) {
555 PDU* last = &lop;
556 while (last->inner_pdu()) {
557 last = last->inner_pdu();
558 }
559 last->inner_pdu(rop.clone());
560 return lop;
561}
562
568template<typename T>
569T operator/ (T lop, const PDU& rop) {
570 lop /= rop;
571 return lop;
572}
573
579template<typename T>
580T* operator/= (T* lop, const PDU& rop) {
581 *lop /= rop;
582 return lop;
583}
584
585namespace Internals {
586 template<typename T>
588 typedef T type;
589 };
590
591 template<typename T>
592 struct remove_pointer<T*> {
593 typedef T type;
594 };
595}
596
597template<typename T, typename U>
598T tins_cast(U* pdu) {
599 typedef typename Internals::remove_pointer<T>::type TrueT;
600 return pdu && (TrueT::pdu_flag == pdu->pdu_type()) ?
601 static_cast<T>(pdu) : 0;
602}
603
604template<typename T, typename U>
605T& tins_cast(U& pdu) {
606 T* ptr = tins_cast<T*>(&pdu);
607 if (!ptr) {
608 throw bad_tins_cast();
609 }
610 return* ptr;
611}
612
613} // Tins
614
615#endif // TINS_PDU_H
Abstraction of a network interface.
Definition network_interface.h:47
Base class for protocol data units.
Definition pdu.h:107
endian_type
Definition pdu.h:117
static const endian_type endianness
Definition pdu.h:193
PDU()
Default constructor.
Definition pdu.cpp:50
void copy_inner_pdu(const PDU &pdu)
Copy other PDU's inner PDU(if any).
Definition pdu.cpp:69
PDU(PDU &&rhs) TINS_NOEXCEPT
Move constructor.
Definition pdu.h:237
virtual uint32_t header_size() const =0
The header's size.
virtual PDU * clone() const =0
Clones this packet.
byte_array serialization_type
Definition pdu.h:112
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz)=0
Serializes this TCP PDU.
virtual void prepare_for_serialize()
Prepares this PDU for serialization.
Definition pdu.cpp:75
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
PDU * parent_pdu() const
Definition pdu.h:305
const T * find_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:380
virtual uint32_t trailer_size() const
Trailer's size.
Definition pdu.h:277
T * find_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:363
T & rfind_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:394
virtual PDUType pdu_type() const =0
Getter for the PDU's type.
serialization_type serialize()
Serializes the whole chain of PDU's, including this one.
Definition pdu.cpp:129
const T & rfind_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:408
PDU * inner_pdu() const
Getter for the inner PDU.
Definition pdu.h:297
virtual PDU * recv_response(PacketSender &sender, const NetworkInterface &iface)
Receives a matching response for this packet.
Definition pdu.cpp:100
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition pdu.h:471
PDU & operator=(PDU &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition pdu.h:250
virtual bool matches_response(const uint8_t *ptr, uint32_t total_sz) const
Check whether ptr points to a valid response for this PDU.
Definition pdu.cpp:104
virtual void send(PacketSender &sender, const NetworkInterface &iface)
Send the stack of PDUs through a PacketSender.
Definition pdu.cpp:96
Sends packets through a network interface.
Definition packet_sender.h:118
Exception thrown when a PDU is not found when using PDU::rfind_pdu.
Definition exceptions.h:98
The Tins namespace.
Definition address_range.h:38
std::vector< uint8_t > byte_array
Definition pdu.h:50
T & operator/=(T &lop, const PDU &rop)
Concatenation operator.
Definition pdu.h:554
AddressRange< HWAddress< n > > operator/(const HWAddress< n > &addr, int mask)
Constructs an AddressRange from a base address and a mask.
Definition address_range.h:308
metadata()
Default constructor.
Definition pdu.cpp:38
PDUType current_pdu_type
Definition pdu.h:218
uint32_t header_size
Definition pdu.h:213
PDUType next_pdu_type
Definition pdu.h:223