libtins 4.4
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 UNKNOWN = 999,
184 USER_DEFINED_PDU = 1000
185 };
186
191 static const endian_type endianness = BE;
192
196 struct metadata {
200 metadata();
201
206 metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
207
211 uint32_t header_size;
212
217
222 };
223
227 PDU();
228
229 #if TINS_IS_CXX11
235 PDU(PDU &&rhs) TINS_NOEXCEPT
236 : inner_pdu_(0), parent_pdu_(0) {
237 std::swap(inner_pdu_, rhs.inner_pdu_);
238 if (inner_pdu_) {
239 inner_pdu_->parent_pdu(this);
240 }
241 }
242
248 PDU& operator=(PDU &&rhs) TINS_NOEXCEPT {
249 delete inner_pdu_;
250 inner_pdu_ = 0;
251 std::swap(inner_pdu_, rhs.inner_pdu_);
252 if (inner_pdu_) {
253 inner_pdu_->parent_pdu(this);
254 }
255 return* this;
256 }
257 #endif
258
265 virtual ~PDU();
266
269 virtual uint32_t header_size() const = 0;
270
275 virtual uint32_t trailer_size() const {
276 return 0;
277 }
278
283 uint32_t size() const;
284
289 virtual uint32_t advertised_size() const;
290
295 PDU* inner_pdu() const {
296 return inner_pdu_;
297 }
298
303 PDU* parent_pdu() const {
304 return parent_pdu_;
305 }
306
320 PDU* release_inner_pdu();
321
330 void inner_pdu(PDU* next_pdu);
331
339 void inner_pdu(const PDU& next_pdu);
340
350 serialization_type serialize();
351
360 template<typename T>
361 T* find_pdu(PDUType type = T::pdu_flag) {
362 PDU* pdu = this;
363 while (pdu) {
364 if (pdu->matches_flag(type)) {
365 return static_cast<T*>(pdu);
366 }
367 pdu = pdu->inner_pdu();
368 }
369 return 0;
370 }
371
377 template<typename T>
378 const T* find_pdu(PDUType type = T::pdu_flag) const {
379 return const_cast<PDU*>(this)->find_pdu<T>(type);
380 }
381
391 template<typename T>
392 T& rfind_pdu(PDUType type = T::pdu_flag) {
393 T* ptr = find_pdu<T>(type);
394 if (!ptr) {
395 throw pdu_not_found();
396 }
397 return* ptr;
398 }
399
405 template<typename T>
406 const T& rfind_pdu(PDUType type = T::pdu_flag) const {
407 return const_cast<PDU*>(this)->rfind_pdu<T>(type);
408 }
409
418 virtual PDU* clone() const = 0;
419
437 virtual void send(PacketSender& sender, const NetworkInterface& iface);
438
447 virtual PDU* recv_response(PacketSender& sender, const NetworkInterface& iface);
448
459 virtual bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
460
469 virtual bool matches_flag(PDUType flag) const {
470 return flag == pdu_type();
471 }
472
478 virtual PDUType pdu_type() const = 0;
479protected:
483 PDU(const PDU& other);
484
488 PDU& operator=(const PDU& other);
489
494 void copy_inner_pdu(const PDU& pdu);
495
507 virtual void prepare_for_serialize();
508
515 void serialize(uint8_t* buffer, uint32_t total_sz);
516
525 virtual void write_serialization(uint8_t* buffer, uint32_t total_sz) = 0;
526private:
527 void parent_pdu(PDU* parent);
528
529 PDU* inner_pdu_;
530 PDU* parent_pdu_;
531};
532
551template<typename T>
552T& operator/= (T& lop, const PDU& rop) {
553 PDU* last = &lop;
554 while (last->inner_pdu()) {
555 last = last->inner_pdu();
556 }
557 last->inner_pdu(rop.clone());
558 return lop;
559}
560
566template<typename T>
567T operator/ (T lop, const PDU& rop) {
568 lop /= rop;
569 return lop;
570}
571
577template<typename T>
578T* operator/= (T* lop, const PDU& rop) {
579 *lop /= rop;
580 return lop;
581}
582
583namespace Internals {
584 template<typename T>
586 typedef T type;
587 };
588
589 template<typename T>
590 struct remove_pointer<T*> {
591 typedef T type;
592 };
593}
594
595template<typename T, typename U>
596T tins_cast(U* pdu) {
597 typedef typename Internals::remove_pointer<T>::type TrueT;
598 return pdu && (TrueT::pdu_flag == pdu->pdu_type()) ?
599 static_cast<T>(pdu) : 0;
600}
601
602template<typename T, typename U>
603T& tins_cast(U& pdu) {
604 T* ptr = tins_cast<T*>(&pdu);
605 if (!ptr) {
606 throw bad_tins_cast();
607 }
608 return* ptr;
609}
610
611} // Tins
612
613#endif // TINS_PDU_H
Represents an ARP PDU.
Definition arp.h:50
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:57
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:235
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.
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
PDU * parent_pdu() const
Definition pdu.h:303
const T * find_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:378
virtual uint32_t trailer_size() const
Trailer's size.
Definition pdu.h:275
T * find_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:361
T & rfind_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition pdu.h:392
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:406
PDU * inner_pdu() const
Getter for the inner PDU.
Definition pdu.h:295
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition pdu.h:469
PDU & operator=(PDU &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition pdu.h:248
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
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:552
AddressRange< HWAddress< n > > operator/(const HWAddress< n > &addr, int mask)
Constructs an AddressRange from a base address and a mask.
Definition address_range.h:304
Type used to store a PDU header's data.
Definition pdu.h:196
PDUType current_pdu_type
Definition pdu.h:216
uint32_t header_size
Definition pdu.h:211
PDUType next_pdu_type
Definition pdu.h:221