libtins 4.5
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;
45class NetworkInterface;
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 UNKNOWN = 999,
185 USER_DEFINED_PDU = 1000
186 };
187
192 static const endian_type endianness = BE;
193
197 struct metadata {
201 metadata();
202
207 metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
208
212 uint32_t header_size;
213
218
223 };
224
228 PDU();
229
230 #if TINS_IS_CXX11
236 PDU(PDU &&rhs) TINS_NOEXCEPT
237 : inner_pdu_(0), parent_pdu_(0) {
238 std::swap(inner_pdu_, rhs.inner_pdu_);
239 if (inner_pdu_) {
240 inner_pdu_->parent_pdu(this);
241 }
242 }
243
249 PDU& operator=(PDU &&rhs) TINS_NOEXCEPT {
250 delete inner_pdu_;
251 inner_pdu_ = 0;
252 std::swap(inner_pdu_, rhs.inner_pdu_);
253 if (inner_pdu_) {
254 inner_pdu_->parent_pdu(this);
255 }
256 return* this;
257 }
258 #endif
259
266 virtual ~PDU();
267
270 virtual uint32_t header_size() const = 0;
271
276 virtual uint32_t trailer_size() const {
277 return 0;
278 }
279
284 uint32_t size() const;
285
290 virtual uint32_t advertised_size() const;
291
296 PDU* inner_pdu() const {
297 return inner_pdu_;
298 }
299
304 PDU* parent_pdu() const {
305 return parent_pdu_;
306 }
307
321 PDU* release_inner_pdu();
322
331 void inner_pdu(PDU* next_pdu);
332
340 void inner_pdu(const PDU& next_pdu);
341
351 serialization_type serialize();
352
361 template<typename T>
362 T* find_pdu(PDUType type = T::pdu_flag) {
363 PDU* pdu = this;
364 while (pdu) {
365 if (pdu->matches_flag(type)) {
366 return static_cast<T*>(pdu);
367 }
368 pdu = pdu->inner_pdu();
369 }
370 return 0;
371 }
372
378 template<typename T>
379 const T* find_pdu(PDUType type = T::pdu_flag) const {
380 return const_cast<PDU*>(this)->find_pdu<T>(type);
381 }
382
392 template<typename T>
393 T& rfind_pdu(PDUType type = T::pdu_flag) {
394 T* ptr = find_pdu<T>(type);
395 if (!ptr) {
396 throw pdu_not_found();
397 }
398 return* ptr;
399 }
400
406 template<typename T>
407 const T& rfind_pdu(PDUType type = T::pdu_flag) const {
408 return const_cast<PDU*>(this)->rfind_pdu<T>(type);
409 }
410
419 virtual PDU* clone() const = 0;
420
438 virtual void send(PacketSender& sender, const NetworkInterface& iface);
439
448 virtual PDU* recv_response(PacketSender& sender, const NetworkInterface& iface);
449
460 virtual bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
461
470 virtual bool matches_flag(PDUType flag) const {
471 return flag == pdu_type();
472 }
473
479 virtual PDUType pdu_type() const = 0;
480protected:
484 PDU(const PDU& other);
485
489 PDU& operator=(const PDU& other);
490
495 void copy_inner_pdu(const PDU& pdu);
496
508 virtual void prepare_for_serialize();
509
516 void serialize(uint8_t* buffer, uint32_t total_sz);
517
526 virtual void write_serialization(uint8_t* buffer, uint32_t total_sz) = 0;
527private:
528 void parent_pdu(PDU* parent);
529
530 PDU* inner_pdu_;
531 PDU* parent_pdu_;
532};
533
552template<typename T>
553T& operator/= (T& lop, const PDU& rop) {
554 PDU* last = &lop;
555 while (last->inner_pdu()) {
556 last = last->inner_pdu();
557 }
558 last->inner_pdu(rop.clone());
559 return lop;
560}
561
567template<typename T>
568T operator/ (T lop, const PDU& rop) {
569 lop /= rop;
570 return lop;
571}
572
578template<typename T>
579T* operator/= (T* lop, const PDU& rop) {
580 *lop /= rop;
581 return lop;
582}
583
584namespace Internals {
585 template<typename T>
587 typedef T type;
588 };
589
590 template<typename T>
591 struct remove_pointer<T*> {
592 typedef T type;
593 };
594}
595
596template<typename T, typename U>
597T tins_cast(U* pdu) {
598 typedef typename Internals::remove_pointer<T>::type TrueT;
599 return pdu && (TrueT::pdu_flag == pdu->pdu_type()) ?
600 static_cast<T>(pdu) : 0;
601}
602
603template<typename T, typename U>
604T& tins_cast(U& pdu) {
605 T* ptr = tins_cast<T*>(&pdu);
606 if (!ptr) {
607 throw bad_tins_cast();
608 }
609 return* ptr;
610}
611
612} // Tins
613
614#endif // TINS_PDU_H
Represents an ARP PDU.
Definition constants.h:97
Represents the DHCP PDU.
Definition dhcp.h:67
Represents a DHCPv6 PDU.
Definition dhcpv6.h:52
Represents a DNS PDU.
Definition dns.h:85
Class representing an IEEE 802.3 PDU.
Definition dot3.h:46
Represents the EAP encapsulation over LAN.
Definition eapol.h:56
Class that represents an ICMP PDU.
Definition icmp.h:65
Represents an ICMPv6 PDU.
Definition icmpv6.h:58
Class that represents an IP PDU.
Definition ip.h:63
Definition ipv6.h:54
Representing a LLC frame.
Definition llc.h:47
Represents an MPLS PDU.
Definition mpls.h:46
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
PDU(PDU &&rhs) TINS_NOEXCEPT
Move constructor.
Definition pdu.h:236
virtual uint32_t header_size() const =0
The header's size.
virtual PDU * clone() const =0
Clones this packet.
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz)=0
Serializes this TCP PDU.
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
PDU * parent_pdu() const
Definition pdu.h:304
const T * find_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:379
byte_array serialization_type
Definition pdu.h:112
virtual uint32_t trailer_size() const
Trailer's size.
Definition pdu.h:276
T * find_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:362
T & rfind_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:393
virtual PDUType pdu_type() const =0
Getter for the PDU's type.
const T & rfind_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:407
PDU * inner_pdu() const
Getter for the inner PDU.
Definition pdu.h:296
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition pdu.h:470
PDU & operator=(PDU &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition pdu.h:249
Sends packets through a network interface.
Definition packet_sender.h:118
Class that represents the RC4 EAPOL PDU.
Definition eapol.h:198
Class that represents the RSN EAPOL PDU.
Definition eapol.h:397
Represents a Linux cooked-mode capture (SLL) PDU.
Definition sll.h:45
Represents a SNAP frame.
Definition snap.h:48
Represents a Spanning Tree Protocol PDU.
Definition stp.h:44
Represents a TCP PDU.
Definition tcp.h:76
Represents an UDP PDU.
Definition udp.h:63
Represents a VXLAN PDU.
Definition vxlan.h:17
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:553
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
Type used to store a PDU header's data.
Definition pdu.h:197
PDUType current_pdu_type
Definition pdu.h:217
uint32_t header_size
Definition pdu.h:212
PDUType next_pdu_type
Definition pdu.h:222