libtins  4.0
Classes | Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
Tins::PDU Class Referenceabstract

Base class for protocol data units. More...

#include <pdu.h>

Inheritance diagram for Tins::PDU:
Tins::ARP Tins::BootP Tins::DHCPv6 Tins::DNS Tins::Dot11 Tins::Dot1Q Tins::Dot3 Tins::EAPOL Tins::EthernetII Tins::ICMP Tins::ICMPv6 Tins::IP Tins::IPSecAH Tins::IPSecESP Tins::IPv6 Tins::LLC Tins::Loopback Tins::MPLS Tins::PDUCacher< T > Tins::PPPoE Tins::RadioTap Tins::RawPDU Tins::SLL Tins::SNAP Tins::STP Tins::TCP Tins::UDP

Classes

struct  metadata
 Type used to store a PDU header's data. More...
 

Public Types

enum  endian_type { BE, LE }
 
enum  PDUType {
  RAW, ETHERNET_II, IEEE802_3, DOT3 = IEEE802_3,
  RADIOTAP, DOT11, DOT11_ACK, DOT11_ASSOC_REQ,
  DOT11_ASSOC_RESP, DOT11_AUTH, DOT11_BEACON, DOT11_BLOCK_ACK,
  DOT11_BLOCK_ACK_REQ, DOT11_CF_END, DOT11_DATA, DOT11_CONTROL,
  DOT11_DEAUTH, DOT11_DIASSOC, DOT11_END_CF_ACK, DOT11_MANAGEMENT,
  DOT11_PROBE_REQ, DOT11_PROBE_RESP, DOT11_PS_POLL, DOT11_REASSOC_REQ,
  DOT11_REASSOC_RESP, DOT11_RTS, DOT11_QOS_DATA, LLC,
  SNAP, IP, ARP, TCP,
  UDP, ICMP, BOOTP, DHCP,
  EAPOL, RC4EAPOL, RSNEAPOL, DNS,
  LOOPBACK, IPv6, ICMPv6, SLL,
  DHCPv6, DOT1Q, PPPOE, STP,
  PPI, IPSEC_AH, IPSEC_ESP, PKTAP,
  MPLS, UNKNOWN = 999, USER_DEFINED_PDU = 1000
}
 Enum which identifies each type of PDU. More...
 
typedef byte_array serialization_type
 

Public Member Functions

 PDU ()
 Default constructor.
 
 PDU (PDU &&rhs) TINS_NOEXCEPT
 Move constructor. More...
 
PDUoperator= (PDU &&rhs) TINS_NOEXCEPT
 Move assignment operator. More...
 
virtual ~PDU ()
 PDU destructor. More...
 
virtual uint32_t header_size () const =0
 The header's size.
 
virtual uint32_t trailer_size () const
 Trailer's size. More...
 
uint32_t size () const
 The whole chain of PDU's size, including this one. More...
 
PDUinner_pdu () const
 Getter for the inner PDU. More...
 
PDUparent_pdu () const
 
PDUrelease_inner_pdu ()
 Releases the inner PDU. More...
 
void inner_pdu (PDU *next_pdu)
 Sets the child PDU. More...
 
void inner_pdu (const PDU &next_pdu)
 Sets the child PDU. More...
 
serialization_type serialize ()
 Serializes the whole chain of PDU's, including this one. More...
 
template<typename T >
T * find_pdu (PDUType type=T::pdu_flag)
 Finds and returns the first PDU that matches the given flag. More...
 
template<typename T >
const T * find_pdu (PDUType type=T::pdu_flag) const
 Finds and returns the first PDU that matches the given flag. More...
 
template<typename T >
T & rfind_pdu (PDUType type=T::pdu_flag)
 Finds and returns the first PDU that matches the given flag. More...
 
template<typename T >
const T & rfind_pdu (PDUType type=T::pdu_flag) const
 Finds and returns the first PDU that matches the given flag. More...
 
virtual PDUclone () const =0
 Clones this packet. More...
 
virtual void send (PacketSender &sender, const NetworkInterface &iface)
 Send the stack of PDUs through a PacketSender. More...
 
virtual PDUrecv_response (PacketSender &sender, const NetworkInterface &iface)
 Receives a matching response for this packet. More...
 
virtual bool matches_response (const uint8_t *ptr, uint32_t total_sz) const
 Check whether ptr points to a valid response for this PDU. More...
 
virtual bool matches_flag (PDUType flag) const
 Check whether this PDU matches the specified flag. More...
 
virtual PDUType pdu_type () const =0
 Getter for the PDU's type. More...
 

Static Public Attributes

static const endian_type endianness = BE
 

Protected Member Functions

 PDU (const PDU &other)
 Copy constructor.
 
PDUoperator= (const PDU &other)
 Copy assignment operator.
 
void copy_inner_pdu (const PDU &pdu)
 Copy other PDU's inner PDU(if any). More...
 
virtual void prepare_for_serialize ()
 Prepares this PDU for serialization. More...
 
void serialize (uint8_t *buffer, uint32_t total_sz)
 Serializes this PDU and propagates this action to child PDUs. More...
 
virtual void write_serialization (uint8_t *buffer, uint32_t total_sz)=0
 Serializes this TCP PDU. More...
 

Detailed Description

Base class for protocol data units.

Represents a PDU which holds raw data.

Every PDU implementation inherits from this class.

PDUs can contain 0 or 1 inner PDU. By stacking several PDUs together, you can construct packets. These are created upwards: upper layers will be children of the lower ones.

If you want to find a specific protocol within a PDU chain, you can use PDU::find_pdu and PDU::rfind_pdu. Both of them take a template parameter that indicates the PDU type you are looking for. The first one returns a pointer to the first object of that type, and the second one returns a reference (and throws if it is not found).

For example:

// Take a whole packet from somewhere.
EthernetII packet = ...;
// Find the IP layer
const IP* ip = packet.find_pdu<IP>();
if(ip) {
// If the pointer is not null, then it will point to the IP layer
}
// Find the TCP layer. This will throw a pdu_not_found exception
// if there is no TCP layer in this packet.
const TCP& tcp = packet.rfind_pdu<TCP>();

PDU objects can be serialized. Serialization converts the entire PDU stack into a vector of bytes. This process might modify some parameters on packets depending on which protocols are used in it. For example:

If you want to serialize a packet, just use PDU::serialize:

// Construct a packet
EthernetII packet = EthernetII() / IP() / TCP() / RawPDU("hello");
// Now serialize it. This is a std::vector<uint8_t>.
PDU::serialization_type buffer = packet.serialize();

This class is a wrapper over a byte array. It can be used to hold the payload sent over transport layer protocols (such as TCP or UDP).

While sniffing, this class is the one that will hold transport layer protocols' payload. You can simply convert a RawPDU into a specific application layer protocol using the RawPDU::to method:

// Get a RawPDU from somewhere
RawPDU raw = get_raw_pdu();
// Parse it as a DHCP PDU.
DHCP dhcp = raw.to<DHCP>();
// Or parse it as DNS. Of course this will fail if the contents
// don't look like DNS
DNS dns = raw.to<DNS>();

Member Typedef Documentation

The type that will be returned when serializing PDUs.

Member Enumeration Documentation

The typep used to identify the endianness of every PDU.

Enum which identifies each type of PDU.

This enum is used to identify the PDU type.

Constructor & Destructor Documentation

Tins::PDU::PDU ( PDU &&  rhs)
inline

Move constructor.

Parameters
rhsThe PDU to be moved.
Tins::PDU::~PDU ( )
virtual

PDU destructor.

Deletes the inner pdu, as a consequence every child pdu is deleted.

Member Function Documentation

virtual PDU* Tins::PDU::clone ( ) const
pure virtual
void Tins::PDU::copy_inner_pdu ( const PDU pdu)
protected

Copy other PDU's inner PDU(if any).

Parameters
pduThe PDU from which to copy the inner PDU.
template<typename T >
T* Tins::PDU::find_pdu ( PDUType  type = T::pdu_flag)
inline

Finds and returns the first PDU that matches the given flag.

This method searches for the first PDU which has the same type flag as the given one. If the first PDU matches that flag, it is returned. If no PDU matches, 0 is returned.

Parameters
flagThe flag which being searched.
template<typename T >
const T* Tins::PDU::find_pdu ( PDUType  type = T::pdu_flag) const
inline

Finds and returns the first PDU that matches the given flag.

Parameters
flagThe flag which being searched.
PDU* Tins::PDU::inner_pdu ( ) const
inline

Getter for the inner PDU.

Returns
The current inner PDU. Might be a null pointer.
void Tins::PDU::inner_pdu ( PDU next_pdu)

Sets the child PDU.

When setting a new inner_pdu, the instance takesownership of the object, therefore deleting it when it's no longer required.

Parameters
next_pduThe new child PDU.
void Tins::PDU::inner_pdu ( const PDU next_pdu)

Sets the child PDU.

The PDU parameter is cloned using PDU::clone.

Parameters
next_pduThe new child PDU.
virtual bool Tins::PDU::matches_flag ( PDUType  flag) const
inlinevirtual
bool Tins::PDU::matches_response ( const uint8_t *  ptr,
uint32_t  total_sz 
) const
virtual

Check whether ptr points to a valid response for this PDU.

This method must check whether the buffer pointed by ptr is a valid response for this PDU. If it is valid, then it might want to propagate the call to the next PDU. Note that in some cases, such as ICMP Host Unreachable, there is no need to ask the next layer for matching.

Parameters
ptrThe pointer to the buffer.
total_szThe size of the buffer.

Reimplemented in Tins::ICMPv6, Tins::DNS, Tins::DHCPv6, Tins::IP, Tins::TCP, Tins::ICMP, Tins::RadioTap, Tins::IPv6, Tins::ARP, Tins::BootP, Tins::Dot1Q, Tins::RawPDU, Tins::EthernetII, Tins::Dot3, Tins::UDP, Tins::PDUCacher< T >, and Tins::Loopback.

PDU& Tins::PDU::operator= ( PDU &&  rhs)
inline

Move assignment operator.

Parameters
rhsThe PDU to be moved.
PDU* Tins::PDU::parent_pdu ( ) const
inline

Getter for the parent PDU

Returns
The current parent PDU. Might be a null pointer.
virtual PDUType Tins::PDU::pdu_type ( ) const
pure virtual
void Tins::PDU::prepare_for_serialize ( )
protectedvirtual

Prepares this PDU for serialization.

This method is called before the inner PDUs are serialized. It's useful in situations such as when serializing IP PDUs, which don't contain any link layer encapsulation, and therefore require to set the source IP address before the TCP/UDP checksum is calculated.

By default, this method does nothing

PDU * Tins::PDU::recv_response ( PacketSender sender,
const NetworkInterface iface 
)
virtual

Receives a matching response for this packet.

This method should act as a proxy for PacketSender::recv_lX methods.

Parameters
senderThe packet sender which will receive the packet.
ifaceThe interface in which to expect the response.

Reimplemented in Tins::IP, Tins::IPv6, Tins::EthernetII, Tins::Dot3, and Tins::PDUCacher< T >.

PDU * Tins::PDU::release_inner_pdu ( )

Releases the inner PDU.

This method makes this PDU to no longer own the inner PDU. The current inner PDU is returned, and is not destroyed. That means after calling this function, you are responsible for using operator delete on the returned pointer.

Use this method if you want to somehow re-use a PDU that is already owned by another PDU.

Returns
The current inner PDU. Might be 0.
template<typename T >
T& Tins::PDU::rfind_pdu ( PDUType  type = T::pdu_flag)
inline

Finds and returns the first PDU that matches the given flag.

If the PDU is not found, a pdu_not_found exception is thrown.

See also
PDU::find_pdu
Parameters
flagThe flag which being searched.
template<typename T >
const T& Tins::PDU::rfind_pdu ( PDUType  type = T::pdu_flag) const
inline

Finds and returns the first PDU that matches the given flag.

Parameters
flagThe flag which being searched.
void Tins::PDU::send ( PacketSender sender,
const NetworkInterface iface 
)
virtual

Send the stack of PDUs through a PacketSender.

This method will be called only for the PDU on the bottom of the stack, therefore it should only implement this method if it can be sent.

PacketSender implements specific methods to send packets which start on every valid TCP/IP stack layer; this should only be a proxy for those methods.

If this PDU does not represent a link layer protocol, then the interface argument will be ignored.

Parameters
senderThe PacketSender which will send the packet.
ifaceThe network interface in which this packet will be sent.

Reimplemented in Tins::IP, Tins::Dot11, Tins::IPv6, Tins::RadioTap, Tins::EthernetII, Tins::Dot3, and Tins::PDUCacher< T >.

PDU::serialization_type Tins::PDU::serialize ( )

Serializes the whole chain of PDU's, including this one.

This allocates a std::vector of size size(), and fills it with the serialization this PDU, and all of the inner ones'.

Returns
serialization_type containing the serialization of the whole stack of PDUs.
void Tins::PDU::serialize ( uint8_t *  buffer,
uint32_t  total_sz 
)
protected

Serializes this PDU and propagates this action to child PDUs.

Parameters
bufferThe buffer in which to store this PDU's serialization.
total_szThe total size of the buffer.
uint32_t Tins::PDU::size ( ) const

The whole chain of PDU's size, including this one.

Returns the sum of this and all children PDUs' size.

virtual uint32_t Tins::PDU::trailer_size ( ) const
inlinevirtual

Trailer's size.

Some protocols require a trailer(like Ethernet). This defaults to 0.

Reimplemented in Tins::ICMPv6, Tins::RadioTap, Tins::ICMP, Tins::EthernetII, and Tins::Dot1Q.

virtual void Tins::PDU::write_serialization ( uint8_t *  buffer,
uint32_t  total_sz 
)
protectedpure virtual

Serializes this TCP PDU.

Each PDU must override this method and implement it's own serialization.

Parameters
bufferThe buffer in which the PDU will be serialized.
total_szThe size available in the buffer.

Implemented in Tins::BootP.

Member Data Documentation

const endian_type Tins::PDU::endianness = BE
static

The endianness used by this PDU. This can be overriden by subclasses.


The documentation for this class was generated from the following files: