libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
Public Types | Public Member Functions | Protected Member Functions | List of all members
Tins::BaseSniffer Class Reference

Base class for sniffers. More...

#include <sniffer.h>

Inheritance diagram for Tins::BaseSniffer:
Tins::FileSniffer Tins::Sniffer

Public Types

typedef SnifferIterator iterator
 

Public Member Functions

 BaseSniffer (BaseSniffer &&rhs) TINS_NOEXCEPT
 Move constructor. This constructor is available only in C++11.
 
BaseSnifferoperator= (BaseSniffer &&rhs) TINS_NOEXCEPT
 Move assignment operator. This operator is available only in C++11.
 
virtual ~BaseSniffer ()
 Sniffer destructor. This frees all memory used by the pcap handle.
 
PtrPacket next_packet ()
 Compiles a filter and uses it to capture one packet. More...
 
template<typename Functor >
void sniff_loop (Functor function, uint32_t max_packets=0)
 Starts a sniffing loop, using a callback functor for every sniffed packet. More...
 
bool set_filter (const std::string &filter)
 Sets a filter on this sniffer. More...
 
void stop_sniff ()
 Stops sniffing loops. More...
 
int get_fd ()
 Gets the file descriptor associated with the sniffer.
 
bool set_direction (pcap_direction_t d)
 Sets direction for the sniffer. More...
 
void set_timeout (int ms)
 Sets the read timeout for this sniffer. More...
 
void set_extract_raw_pdus (bool value)
 Sets whether to extract RawPDUs or fully parsed packets. More...
 
int link_type () const
 Retrieves this sniffer's link type. More...
 
iterator begin ()
 
iterator end ()
 
pcap_t * get_pcap_handle ()
 
const pcap_t * get_pcap_handle () const
 

Protected Member Functions

 BaseSniffer ()
 
void set_pcap_handle (pcap_t *pcap_handle)
 
void set_if_mask (bpf_u_int32 if_mask)
 
bpf_u_int32 get_if_mask () const
 

Detailed Description

Base class for sniffers.

This class implements the basic sniffing operations. Subclasses should only initialize this object using a pcap_t pointer, which will be used to extract packets.

Initialization must be done using the BaseSniffer::init method.

Member Typedef Documentation

The iterator type.

Constructor & Destructor Documentation

Tins::BaseSniffer::BaseSniffer ( )
protected

Default constructor.

Member Function Documentation

BaseSniffer::iterator Tins::BaseSniffer::begin ( )

Retrieves an iterator to the next packet in this sniffer.

BaseSniffer::iterator Tins::BaseSniffer::end ( )

Retrieves an end iterator.

pcap_t * Tins::BaseSniffer::get_pcap_handle ( )

Retrieves the pcap handle used by this sniffer.

const pcap_t * Tins::BaseSniffer::get_pcap_handle ( ) const

Retrieves the pcap handle used by this sniffer.

int Tins::BaseSniffer::link_type ( ) const

Retrieves this sniffer's link type.

This calls pcap_datalink on the stored pcap handle and returns its result.

PtrPacket Tins::BaseSniffer::next_packet ( )

Compiles a filter and uses it to capture one packet.

This method returns the first valid sniffed packet that matches the sniffer's filter, or the first sniffed packet if no filter has been set.

The return type is a thin wrapper over a PDU* and a Timestamp object. This wrapper can be both implicitly converted to a PDU* and a Packet object. So doing this:

Sniffer s(...);
std::unique_ptr<PDU> pdu(s.next_packet());
// Packet takes care of the PDU*.
Packet packet(s.next_packet());

Is fine, but this:

// bad!!
PtrPacket p = s.next_packet();

Is not, since PtrPacket can't be copy constructed.

See Also
Packet::release_pdu
Returns
A captured packet. If an error occured, PtrPacket::pdu will return 0. Caller takes ownership of the PDU pointer stored in the PtrPacket.
bool Tins::BaseSniffer::set_direction ( pcap_direction_t  d)

Sets direction for the sniffer.

This calls pcap_setdirection using the provided parameter.

Parameters
dThe direction for the sniffer.
void Tins::BaseSniffer::set_extract_raw_pdus ( bool  value)

Sets whether to extract RawPDUs or fully parsed packets.

By default, packets will be parsed starting from link layer. However, if you're parsing a lot of traffic, then you might want to extract packets and push them into a queue, so a consumer can parse them when they're popped.

This method allows doing that. If the parameter is true, then packets taken from this BaseSniffer will only contain a RawPDU which will have to entire contents of the packet.

Parameters
valueWhether to extract RawPDUs or not.
bool Tins::BaseSniffer::set_filter ( const std::string &  filter)

Sets a filter on this sniffer.

Parameters
filterThe filter to be set.
Returns
True iif it was possible to apply the filter.
void Tins::BaseSniffer::set_timeout ( int  ms)

Sets the read timeout for this sniffer.

This calls pcap_set_timeout using the provided parameter.

Parameters
msThe amount of milliseconds.
template<typename Functor >
void Tins::BaseSniffer::sniff_loop ( Functor  function,
uint32_t  max_packets = 0 
)

Starts a sniffing loop, using a callback functor for every sniffed packet.

The functor must implement an operator with one of the following signatures:

bool(PDU&);
bool(const PDU&);
// These two are only allowed when compiling in C++11 mode
bool(Packet&);
bool(const Packet&);

This functor will be called using the each of the sniffed packets as its argument. Using PDU member functions that modify the PDU, such as PDU::release_inner_pdu, is perfectly valid.

Note that if you're using a functor object, it will be copied using its copy constructor, so it should be some kind of proxy to another object which will process the packets(e.g. std::bind).

Sniffing will stop when either max_packets are sniffed(if it is != 0), or when the functor returns false.

Note that the pcap handle stored in a BaseSniffer will always be the same. This means that if you start sniffing using sniff_loop, then stop and at some point in the future you call sniff_loop again, you will keep iterating over the same handle. If the handle points to a pcap file, then you will continue processing packets from it. If the handle points to a network device, you will keep sniffing from it.

This method catches both malformed_packet and pdu_not_found exceptions, which allows writing much cleaner code, since you can call PDU::rfind_pdu without worrying about catching the exception that can be thrown. This allows writing code such as the following:

bool callback(const PDU& pdu) {
// If either RawPDU is not found, or construction of the DNS
// object fails, the BaseSniffer object will trap the exceptions,
// so we don't need to worry about it.
DNS dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
return true;
}
Parameters
functionThe callback handler object which should process packets.
max_packetsThe maximum amount of packets to sniff. 0 == infinite.
void Tins::BaseSniffer::stop_sniff ( )

Stops sniffing loops.

This method must be called from the same thread from which BaseSniffer::sniff_loop was called.


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