libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
pdu.h
1 /*
2  * Copyright (c) 2016, 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 "macros.h"
37 #include "cxxstd.h"
38 #include "exceptions.h"
39 #include "macros.h"
40 
43 namespace Tins {
44 
45 class PacketSender;
47 
51 typedef std::vector<uint8_t> byte_array;
52 
108 class TINS_API PDU {
109 public:
114 
118  enum endian_type {
119  BE,
120  LE
121  };
122 
128  enum PDUType {
129  RAW,
130  ETHERNET_II,
131  IEEE802_3,
132  DOT3 = IEEE802_3,
133  RADIOTAP,
134  DOT11,
135  DOT11_ACK,
136  DOT11_ASSOC_REQ,
137  DOT11_ASSOC_RESP,
138  DOT11_AUTH,
139  DOT11_BEACON,
140  DOT11_BLOCK_ACK,
141  DOT11_BLOCK_ACK_REQ,
142  DOT11_CF_END,
143  DOT11_DATA,
144  DOT11_CONTROL,
145  DOT11_DEAUTH,
146  DOT11_DIASSOC,
147  DOT11_END_CF_ACK,
148  DOT11_MANAGEMENT,
149  DOT11_PROBE_REQ,
150  DOT11_PROBE_RESP,
151  DOT11_PS_POLL,
152  DOT11_REASSOC_REQ,
153  DOT11_REASSOC_RESP,
154  DOT11_RTS,
155  DOT11_QOS_DATA,
156  LLC,
157  SNAP,
158  IP,
159  ARP,
160  TCP,
161  UDP,
162  ICMP,
163  BOOTP,
164  DHCP,
165  EAPOL,
166  RC4EAPOL,
167  RSNEAPOL,
168  DNS,
169  LOOPBACK,
170  IPv6,
171  ICMPv6,
172  SLL,
173  DHCPv6,
174  DOT1Q,
175  PPPOE,
176  STP,
177  PPI,
178  IPSEC_AH,
179  IPSEC_ESP,
180  PKTAP,
181  MPLS,
182  UNKNOWN = 999,
183  USER_DEFINED_PDU = 1000
184  };
185 
190  static const endian_type endianness = BE;
191 
195  struct metadata {
199  metadata();
200 
205  metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
206 
210  uint32_t header_size;
211 
216 
221  };
222 
226  PDU();
227 
228  #if TINS_IS_CXX11
229 
234  PDU(PDU &&rhs) TINS_NOEXCEPT
235  : inner_pdu_(0) {
236  std::swap(inner_pdu_, rhs.inner_pdu_);
237  }
238 
244  PDU& operator=(PDU &&rhs) TINS_NOEXCEPT {
245  std::swap(inner_pdu_, rhs.inner_pdu_);
246  return* this;
247  }
248  #endif
249 
256  virtual ~PDU();
257 
260  virtual uint32_t header_size() const = 0;
261 
266  virtual uint32_t trailer_size() const {
267  return 0;
268  }
269 
274  uint32_t size() const;
275 
280  PDU* inner_pdu() const {
281  return inner_pdu_;
282  }
283 
297  PDU* release_inner_pdu();
298 
307  void inner_pdu(PDU* next_pdu);
308 
316  void inner_pdu(const PDU& next_pdu);
317 
318 
328  serialization_type serialize();
329 
338  template<typename T>
339  T* find_pdu(PDUType type = T::pdu_flag) {
340  PDU* pdu = this;
341  while (pdu) {
342  if (pdu->matches_flag(type)) {
343  return static_cast<T*>(pdu);
344  }
345  pdu = pdu->inner_pdu();
346  }
347  return 0;
348  }
349 
355  template<typename T>
356  const T* find_pdu(PDUType type = T::pdu_flag) const {
357  return const_cast<PDU*>(this)->find_pdu<T>();
358  }
359 
369  template<typename T>
370  T& rfind_pdu(PDUType type = T::pdu_flag) {
371  T* ptr = find_pdu<T>(type);
372  if (!ptr) {
373  throw pdu_not_found();
374  }
375  return* ptr;
376  }
377 
383  template<typename T>
384  const T& rfind_pdu(PDUType type = T::pdu_flag) const {
385  return const_cast<PDU*>(this)->rfind_pdu<T>();
386  }
387 
396  virtual PDU* clone() const = 0;
397 
415  virtual void send(PacketSender& sender, const NetworkInterface& iface);
416 
425  virtual PDU* recv_response(PacketSender& sender, const NetworkInterface& iface);
426 
437  virtual bool matches_response(const uint8_t* ptr, uint32_t total_sz) const {
438  return false;
439  }
440 
449  virtual bool matches_flag(PDUType flag) const {
450  return flag == pdu_type();
451  }
452 
458  virtual PDUType pdu_type() const = 0;
459 protected:
463  PDU(const PDU& other);
464 
468  PDU& operator=(const PDU& other);
469 
474  void copy_inner_pdu(const PDU& pdu);
475 
489  virtual void prepare_for_serialize(const PDU* parent) { }
490 
498  void serialize(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
499 
509  virtual void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent) = 0;
510 private:
511  PDU* inner_pdu_;
512 };
513 
532 template<typename T>
533 T& operator/= (T& lop, const PDU& rop) {
534  PDU* last = &lop;
535  while (last->inner_pdu()) {
536  last = last->inner_pdu();
537  }
538  last->inner_pdu(rop.clone());
539  return lop;
540 }
541 
547 template<typename T>
548 T operator/ (T lop, const PDU& rop) {
549  lop /= rop;
550  return lop;
551 }
552 
558 template<typename T>
559 T* operator/= (T* lop, const PDU& rop) {
560  *lop /= rop;
561  return lop;
562 }
563 
564 namespace Internals {
565  template<typename T>
566  struct remove_pointer {
567  typedef T type;
568  };
569 
570  template<typename T>
571  struct remove_pointer<T*> {
572  typedef T type;
573  };
574 }
575 
576 template<typename T, typename U>
577 T tins_cast(U* pdu) {
578  typedef typename Internals::remove_pointer<T>::type TrueT;
579  return pdu && (TrueT::pdu_flag == pdu->pdu_type()) ?
580  static_cast<T>(pdu) : 0;
581 }
582 
583 template<typename T, typename U>
584 T& tins_cast(U& pdu) {
585  T* ptr = tins_cast<T*>(&pdu);
586  if (!ptr) {
587  throw bad_tins_cast();
588  }
589  return* ptr;
590 }
591 
592 } // Tins
593 
594 #endif // TINS_PDU_H
PDUType next_pdu_type
Definition: pdu.h:220
virtual bool matches_flag(PDUType flag) const
Check whether this PDU matches the specified flag.
Definition: pdu.h:449
uint32_t header_size
Definition: pdu.h:210
Class that represents an ICMP PDU.
Definition: icmp.h:65
Represents a TCP PDU.
Definition: tcp.h:79
Exception thrown when a PDU is not found when using PDU::rfind_pdu.
Definition: exceptions.h:84
const T & rfind_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition: pdu.h:384
Class that represents an IP PDU.
Definition: ip.h:64
Represents a Linux cooked-mode capture (SLL) PDU.
Definition: sll.h:45
std::vector< uint8_t > byte_array
Definition: pdu.h:46
Represents an MPLS PDU.
Definition: mpls.h:46
Represents a DNS PDU.
Definition: dns.h:78
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
virtual void prepare_for_serialize(const PDU *parent)
Prepares this PDU for serialization.
Definition: pdu.h:489
const T * find_pdu(PDUType type=T::pdu_flag) const
Finds and returns the first PDU that matches the given flag.
Definition: pdu.h:356
T * find_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition: pdu.h:339
Sends packets through a network interface.
Definition: packet_sender.h:117
virtual uint32_t trailer_size() const
Trailer's size.
Definition: pdu.h:266
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.h:437
Represents a Per-Packet Information PDU.
Definition: ppi.h:48
PDU & operator=(PDU &&rhs) TINS_NOEXCEPT
Move assignment operator.
Definition: pdu.h:244
Represents an ARP PDU.
Definition: arp.h:50
Represents an ICMPv6 PDU.
Definition: icmpv6.h:58
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
Definition: pdu.h:566
Represents a DHCPv6 PDU.
Definition: dhcpv6.h:53
Definition: ipv6.h:55
Represents a Spanning Tree Protocol PDU.
Definition: stp.h:44
Represents an UDP PDU.
Definition: udp.h:63
Class representing an IEEE 802.3 PDU.
Definition: dot3.h:46
Representing a LLC frame.
Definition: llc.h:49
Type used to store a PDU header's data.
Definition: pdu.h:195
Class that represents the RC4 EAPOL PDU.
Definition: eapol.h:204
Class that represents the RSN EAPOL PDU.
Definition: eapol.h:403
Abstraction of a network interface.
Definition: network_interface.h:47
T & operator/=(T &lop, const PDU &rop)
Concatenation operator.
Definition: pdu.h:533
PDU * inner_pdu() const
Getter for the inner PDU.
Definition: pdu.h:280
Represents the DHCP PDU.
Definition: dhcp.h:68
Represents the EAP encapsulation over LAN.
Definition: eapol.h:56
Represents a SNAP frame.
Definition: snap.h:49
virtual PDU * clone() const =0
Clones this packet.
PDU(PDU &&rhs) TINS_NOEXCEPT
Move constructor.
Definition: pdu.h:234
byte_array serialization_type
Definition: pdu.h:113
Represents a PKTAP PDU.
Definition: pktap.h:41
T & rfind_pdu(PDUType type=T::pdu_flag)
Finds and returns the first PDU that matches the given flag.
Definition: pdu.h:370
Base class for protocol data units.
Definition: pdu.h:108
PDUType current_pdu_type
Definition: pdu.h:215
endian_type
Definition: pdu.h:118