PcapPlusPlus  21.05
pcpp::PcapLiveDevice Class Reference

#include <PcapLiveDevice.h>

Inheritance diagram for pcpp::PcapLiveDevice:
pcpp::IPcapDevice pcpp::IDevice pcpp::IFilterableDevice pcpp::PcapRemoteDevice pcpp::WinPcapLiveDevice

Classes

struct  DeviceConfiguration
 

Public Types

enum  LiveDeviceType { LibPcapDevice, WinPcapDevice, RemoteDevice }
 
enum  DeviceMode { Normal = 0, Promiscuous = 1 }
 
enum  PcapDirection { PCPP_INOUT = 0, PCPP_IN, PCPP_OUT }
 

Public Member Functions

virtual ~PcapLiveDevice ()
 
virtual LiveDeviceType getDeviceType () const
 
std::string getName () const
 
std::string getDesc () const
 
bool getLoopback () const
 
virtual uint32_t getMtu () const
 
virtual LinkLayerType getLinkType () const
 
const std::vector< pcap_addr_t > & getAddresses () const
 
virtual MacAddress getMacAddress () const
 
IPv4Address getIPv4Address () const
 
IPv4Address getDefaultGateway () const
 
const std::vector< IPv4Address > & getDnsServers () const
 
virtual bool startCapture (OnPacketArrivesCallback onPacketArrives, void *onPacketArrivesUserCookie)
 
virtual bool startCapture (OnPacketArrivesCallback onPacketArrives, void *onPacketArrivesUserCookie, int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void *onStatsUpdateUserCookie)
 
virtual bool startCapture (int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void *onStatsUpdateUserCookie)
 
virtual bool startCapture (RawPacketVector &capturedPacketsVector)
 
virtual int startCaptureBlockingMode (OnPacketArrivesStopBlocking onPacketArrives, void *userCookie, int timeout)
 
void stopCapture ()
 
bool captureActive ()
 
bool doMtuCheck (int packetPayloadLength)
 
bool sendPacket (RawPacket const &rawPacket, bool checkMtu=false)
 
bool sendPacket (const uint8_t *packetData, int packetDataLength, int packetPayloadLength)
 
bool sendPacket (const uint8_t *packetData, int packetDataLength, bool checkMtu=false, pcpp::LinkLayerType linkType=pcpp::LINKTYPE_ETHERNET)
 
bool sendPacket (Packet *packet, bool checkMtu=true)
 
virtual int sendPackets (RawPacket *rawPacketsArr, int arrLength, bool checkMtu=false)
 
virtual int sendPackets (Packet **packetsArr, int arrLength, bool checkMtu=true)
 
virtual int sendPackets (const RawPacketVector &rawPackets, bool checkMtu=false)
 
bool open ()
 
bool open (const DeviceConfiguration &config)
 
void close ()
 
virtual void getStatistics (IPcapDevice::PcapStats &stats) const
 
- Public Member Functions inherited from pcpp::IPcapDevice
virtual bool setFilter (std::string filterAsString)
 
bool clearFilter ()
 
- Public Member Functions inherited from pcpp::IDevice
bool isOpened ()
 
- Public Member Functions inherited from pcpp::IFilterableDevice
virtual bool setFilter (GeneralFilter &filter)
 

Additional Inherited Members

- Static Public Member Functions inherited from pcpp::IPcapDevice
static std::string getPcapLibVersionInfo ()
 
static bool verifyFilter (std::string filterAsString)
 
static bool matchPacketWithFilter (std::string filterAsString, RawPacket *rawPacket)
 
static bool matchPacketWithFilter (GeneralFilter &filter, RawPacket *rawPacket)
 

Detailed Description

A class that wraps a network interface (each of the interfaces listed in ifconfig/ipconfig). This class wraps the libpcap capabilities of capturing packets from the network, filtering packets and sending packets back to the network. This class is relevant for Linux applications only. On Windows the WinPcapLiveDevice (which inherits this class) is used. Both classes are almost similar in capabilities, the main difference between them is adapting some capabilities to the specific OS. This class cannot be instantiated by the user (it has a private constructor), as network interfaces aren't dynamic. Instances of this class (one instance per network interface) are created by PcapLiveDeviceList singleton on application startup and the user can get access to them by using PcapLiveDeviceList public methods such as PcapLiveDeviceList::getPcapLiveDeviceByIp()
Main capabilities of this class:

  • Get all available information for this network interfaces such as name, IP addresses, MAC address, MTU, etc. This information is taken from both libpcap and the OS
  • Capture packets from the network. Capturing is always conducted on a different thread. PcapPlusPlus creates this thread when capturing starts and kills it when capturing ends. This prevents the application from being stuck while waiting for packets or processing them. Currently only one capturing thread is allowed, so when the interface is in capture mode, no further capturing is allowed. In addition to capturing the user can get stats on packets that were received by the application, dropped by the NIC (due to full NIC buffers), etc. Stats collection can be initiated by the user by calling getStatistics() or be pushed to the user periodically by supplying a callback and a timeout to startCapture()
  • Send packets back to the network. Sending the packets is done on the caller thread. No additional threads are created for this task

Member Enumeration Documentation

◆ DeviceMode

Device capturing mode

Enumerator
Normal 

Only packets that their destination is this NIC are captured

Promiscuous 

All packets that arrive to the NIC are captured, even packets that their destination isn't this NIC

◆ LiveDeviceType

The type of the live device

Enumerator
LibPcapDevice 

libPcap live device

WinPcapDevice 

WinPcap/Npcap live device

RemoteDevice 

WinPcap/Npcap Remote Capture device

◆ PcapDirection

Set direction for capturing packets (you can read more here: https://www.tcpdump.org/manpages/pcap.3pcap.html#lbAI)

Enumerator
PCPP_INOUT 

Capture traffics both incoming and outgoing

PCPP_IN 

Only capture incoming traffics

PCPP_OUT 

Only capture outgoing traffics

Constructor & Destructor Documentation

◆ ~PcapLiveDevice()

virtual pcpp::PcapLiveDevice::~PcapLiveDevice ( )
virtual

A destructor for this class

Member Function Documentation

◆ captureActive()

bool pcpp::PcapLiveDevice::captureActive ( )

Check if a capture thread is running

Returns
True if a capture thread is currently running

◆ close()

void pcpp::PcapLiveDevice::close ( )
virtual

Close the device

Implements pcpp::IDevice.

◆ doMtuCheck()

bool pcpp::PcapLiveDevice::doMtuCheck ( int  packetPayloadLength)

Checks whether the packetPayloadLength is larger than the device MTU. Logs an error if check fails

Parameters
[in]packetPayloadLengthThe length of the IP layer of the packet
Returns
True if the packetPayloadLength is less than or equal to the device MTU

◆ getAddresses()

const std::vector<pcap_addr_t>& pcpp::PcapLiveDevice::getAddresses ( ) const
inline
Returns
A vector containing all addresses defined for this interface, each in pcap_addr_t struct

◆ getDefaultGateway()

IPv4Address pcpp::PcapLiveDevice::getDefaultGateway ( ) const
Returns
The default gateway defined for this interface. If no default gateway is defined, if it's not IPv4 or if couldn't extract default gateway IPv4Address::Zero will be returned. If multiple gateways were defined the first one will be returned

◆ getDesc()

std::string pcpp::PcapLiveDevice::getDesc ( ) const
inline
Returns
A human-readable description of the device, taken from pcap_if_t->description. May be NULL in some interfaces

◆ getDeviceType()

virtual LiveDeviceType pcpp::PcapLiveDevice::getDeviceType ( ) const
inlinevirtual
Returns
The type of the device (libPcap, WinPcap/Npcap or a remote device)

Reimplemented in pcpp::PcapRemoteDevice, and pcpp::WinPcapLiveDevice.

◆ getDnsServers()

const std::vector<IPv4Address>& pcpp::PcapLiveDevice::getDnsServers ( ) const
Returns
A list of all DNS servers defined for this machine. If this list is empty it means no DNS servers were defined or they couldn't be extracted from some reason. This list is created in PcapLiveDeviceList class and can be also retrieved from there. This method exists for convenience - so it'll be possible to get this list from PcapLiveDevice as well

◆ getIPv4Address()

IPv4Address pcpp::PcapLiveDevice::getIPv4Address ( ) const
Returns
The IPv4 address for this interface. If multiple IPv4 addresses are defined for this interface, the first will be picked. If no IPv4 addresses are defined, a zeroed IPv4 address (IPv4Address::Zero) will be returned

◆ getLinkType()

virtual LinkLayerType pcpp::PcapLiveDevice::getLinkType ( ) const
inlinevirtual
Returns
The device's link layer type

◆ getLoopback()

bool pcpp::PcapLiveDevice::getLoopback ( ) const
inline
Returns
True if this interface is a loopback interface, false otherwise

◆ getMacAddress()

virtual MacAddress pcpp::PcapLiveDevice::getMacAddress ( ) const
inlinevirtual
Returns
The MAC address for this interface

Reimplemented in pcpp::PcapRemoteDevice.

◆ getMtu()

virtual uint32_t pcpp::PcapLiveDevice::getMtu ( ) const
inlinevirtual
Returns
The device's maximum transmission unit (MTU) in bytes

Reimplemented in pcpp::PcapRemoteDevice.

◆ getName()

std::string pcpp::PcapLiveDevice::getName ( ) const
inline
Returns
The name of the device (e.g eth0), taken from pcap_if_t->name

◆ getStatistics()

virtual void pcpp::PcapLiveDevice::getStatistics ( IPcapDevice::PcapStats stats) const
virtual

Get statistics from the device

Parameters
[out]statsAn object containing the stats

Implements pcpp::IPcapDevice.

Reimplemented in pcpp::PcapRemoteDevice.

◆ open() [1/2]

bool pcpp::PcapLiveDevice::open ( )
virtual

Open the device using libpcap pcap_open_live. Opening the device only makes the device ready for use, it doesn't start packet capturing. For packet capturing the user should call startCapture(). This implies that calling this method is a must before calling startCapture() (otherwise startCapture() will fail with a "device not open" error). The device is opened in promiscuous mode

Returns
True if the device was opened successfully, false otherwise. When opening the device fails an error will be printed to log as well

Implements pcpp::IDevice.

Reimplemented in pcpp::PcapRemoteDevice.

◆ open() [2/2]

bool pcpp::PcapLiveDevice::open ( const DeviceConfiguration config)

Enables to open a device in a non-default configuration. Configuration has parameters like packet buffer timeout & size, open in promiscuous/non-promiscuous mode, etc. Please check DeviceConfiguration for more details

Parameters
[in]configThe requested configuration
Returns
Same as open()

◆ sendPacket() [1/4]

bool pcpp::PcapLiveDevice::sendPacket ( RawPacket const &  rawPacket,
bool  checkMtu = false 
)

Send a RawPacket to the network

Parameters
[in]rawPacketA reference to the raw packet to send. This method treats the raw packet as read-only, it doesn't change anything in it
[in]checkMtuWhether the length of the packet's payload should be checked against the MTU. If enabled this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to true if you don't know whether packets fit the live device's MTU and you can afford the overhead.
Returns
True if packet was sent successfully. False will be returned in the following cases (relevant log error is printed in any case):
  • Device is not opened
  • Packet length is 0
  • Packet length is larger than device MTU
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPacket() [2/4]

bool pcpp::PcapLiveDevice::sendPacket ( const uint8_t *  packetData,
int  packetDataLength,
int  packetPayloadLength 
)

Send a buffer containing packet raw data (including all layers) to the network. This particular version of the sendPacket method should only be used if you already have access to the size of the network layer of the packet, since it allows you to check the payload size (see packetPayloadLength parameter) MTU of the live device without incurring a parsing overhead. If the packetPayloadLength is unknown, please use a different implementation of the sendPacket method.

Parameters
[in]packetDataThe buffer containing the packet raw data
[in]packetDataLengthThe length of the buffer (this is the entire packet, including link layer)
[in]packetPayloadLengthThe length of the payload for the data link layer. This includes all data apart from the header for the data link layer.
Returns
True if the packet was sent successfully. False will be returned in the following cases (relevant log error is printed in any case):
  • Device is not opened
  • Packet data length is 0
  • Packet payload length is larger than device MTU
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPacket() [3/4]

bool pcpp::PcapLiveDevice::sendPacket ( const uint8_t *  packetData,
int  packetDataLength,
bool  checkMtu = false,
pcpp::LinkLayerType  linkType = pcpp::LINKTYPE_ETHERNET 
)

Send a buffer containing packet raw data (including all layers) to the network

Parameters
[in]packetDataThe buffer containing the packet raw data
[in]packetDataLengthThe length of the buffer
[in]checkMtuWhether the length of the packet's payload should be checked against the MTU. If enabled this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to true if you don't know whether packets fit the live device's MTU and you can afford the overhead.
[in]linkTypeOnly used if checkMtu is true. Defines the layer type for parsing the first layer of the packet. Used for parsing the packet to perform the MTU check. Default value is pcpp::LINKTYPE_ETHERNET. Ensure this parameter matches the linktype of the packet if checkMtu is true.
Returns
True if packet was sent successfully. False will be returned in the following cases (relevant log error is printed in any case):
  • Device is not opened
  • Packet length is 0
  • Packet length is larger than device MTU and checkMtu is true
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPacket() [4/4]

bool pcpp::PcapLiveDevice::sendPacket ( Packet packet,
bool  checkMtu = true 
)

Send a parsed Packet to the network

Parameters
[in]packetA pointer to the packet to send. This method treats the packet as read-only, it doesn't change anything in it
[in]checkMtuWhether the length of the packet's payload should be checked against the MTU. Default value is true, since the packet being passed in has already been parsed, so checking the MTU does not incur significant processing overhead.
Returns
True if packet was sent successfully. False will be returned in the following cases (relevant log error is printed in any case):
  • Device is not opened
  • Packet length is 0
  • Packet length is larger than device MTU and checkMtu is true
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPackets() [1/3]

virtual int pcpp::PcapLiveDevice::sendPackets ( RawPacket rawPacketsArr,
int  arrLength,
bool  checkMtu = false 
)
virtual

Send an array of RawPacket objects to the network

Parameters
[in]rawPacketsArrThe array of RawPacket objects to send. This method treats all packets as read-only, it doesn't change anything in them
[in]arrLengthThe length of the array
[in]checkMtuWhether to check the size of the packet payload against MTU size. Incurs a parsing overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether packets fit the live device's MTU and you can afford the overhead.
Returns
The number of packets sent successfully. Sending a packet can fail if:
  • Device is not opened. In this case no packets will be sent, return value will be 0
  • Packet length is 0
  • Packet length is larger than device MTU and checkMtu is true
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPackets() [2/3]

virtual int pcpp::PcapLiveDevice::sendPackets ( Packet **  packetsArr,
int  arrLength,
bool  checkMtu = true 
)
virtual

Send an array of pointers to Packet objects to the network

Parameters
[in]packetsArrThe array of pointers to Packet objects to send. This method treats all packets as read-only, it doesn't change anything in them
[in]arrLengthThe length of the array
[in]checkMtuWhether to check the size of the packet payload against MTU size. Default value is true, since the packets being passed in has already been parsed, so checking the MTU does not incur significant processing overhead.
Returns
The number of packets sent successfully. Sending a packet can fail if:
  • Device is not opened. In this case no packets will be sent, return value will be 0
  • Packet length is 0
  • Packet length is larger than device MTU and checkMtu is true
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ sendPackets() [3/3]

virtual int pcpp::PcapLiveDevice::sendPackets ( const RawPacketVector rawPackets,
bool  checkMtu = false 
)
virtual

Send a vector of pointers to RawPacket objects to the network

Parameters
[in]rawPacketsThe array of pointers to RawPacket objects to send. This method treats all packets as read-only, it doesn't change anything in them
[in]checkMtuWhether to check the size of the packet payload against MTU size. Incurs a parsing overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether packets fit the live device's MTU and you can afford the overhead.
Returns
The number of packets sent successfully. Sending a packet can fail if:
  • Device is not opened. In this case no packets will be sent, return value will be 0
  • Packet length is 0
  • Packet length is larger than device MTU and checkMtu is true
  • Packet could not be sent due to some error in libpcap/WinPcap/Npcap

◆ startCapture() [1/4]

virtual bool pcpp::PcapLiveDevice::startCapture ( OnPacketArrivesCallback  onPacketArrives,
void *  onPacketArrivesUserCookie 
)
virtual

Start capturing packets on this network interface (device). Each time a packet is captured the onPacketArrives callback is called. The capture is done on a new thread created by this method, meaning all callback calls are done in a thread other than the caller thread. Capture process will stop and this capture thread will be terminated when calling stopCapture(). This method must be called after the device is opened (i.e the open() method was called), otherwise an error will be returned.

Parameters
[in]onPacketArrivesA callback that is called each time a packet is captured
[in]onPacketArrivesUserCookieA pointer to a user provided object. This object will be transferred to the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that give context to the capture callback, for example: objects that counts packets, manages flow state or manages the application state according to the packet that was captured
Returns
True if capture started successfully, false if (relevant log error is printed in any case):
  • Capture is already running
  • Device is not opened
  • Capture thread could not be created

◆ startCapture() [2/4]

virtual bool pcpp::PcapLiveDevice::startCapture ( OnPacketArrivesCallback  onPacketArrives,
void *  onPacketArrivesUserCookie,
int  intervalInSecondsToUpdateStats,
OnStatsUpdateCallback  onStatsUpdate,
void *  onStatsUpdateUserCookie 
)
virtual

Start capturing packets on this network interface (device) with periodic stats collection. Each time a packet is captured the onPacketArrives callback is called. In addition, each intervalInSecondsToUpdateStats seconds stats are collected from the device and the onStatsUpdate callback is called. Both the capture and periodic stats collection are done on new threads created by this method, each on a different thread, meaning all callback calls are done in threads other than the caller thread. Capture process and stats collection will stop and threads will be terminated when calling stopCapture(). This method must be called after the device is opened (i.e the open() method was called), otherwise an error will be returned.

Parameters
[in]onPacketArrivesA callback that is called each time a packet is captured
[in]onPacketArrivesUserCookieA pointer to a user provided object. This object will be transferred to the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that give context to the capture callback, for example: objects that counts packets, manages flow state or manages the application state according to the packet that was captured
[in]intervalInSecondsToUpdateStatsThe interval in seconds to activate periodic stats collection
[in]onStatsUpdateA callback that will be called each time intervalInSecondsToUpdateStats expires and stats are collected. This callback will contain the collected stats
[in]onStatsUpdateUserCookieA pointer to a user provided object. This object will be transferred to the onStatsUpdate callback each time it is called
Returns
True if capture started successfully, false if (relevant log error is printed in any case):
  • Capture is already running
  • Device is not opened
  • Capture thread could not be created
  • Stats collection thread could not be created

Reimplemented in pcpp::WinPcapLiveDevice.

◆ startCapture() [3/4]

virtual bool pcpp::PcapLiveDevice::startCapture ( int  intervalInSecondsToUpdateStats,
OnStatsUpdateCallback  onStatsUpdate,
void *  onStatsUpdateUserCookie 
)
virtual

Start capturing packets on this network interface (device) with periodic stats collection only. This means that packets arriving to the network interface aren't delivered to the user but only counted. Each intervalInSecondsToUpdateStats seconds stats are collected from the device and the onStatsUpdate callback is called with the updated counters. The periodic stats collection is done on a new thread created by this method, meaning all callback calls are done in threads other than the caller thread. Stats collection will stop and threads will be terminated when calling stopCapture(). This method must be called after the device is opened (i.e the open() method was called), otherwise an error will be returned.

Parameters
[in]intervalInSecondsToUpdateStatsThe interval in seconds to activate periodic stats collection
[in]onStatsUpdateA callback that will be called each time intervalInSecondsToUpdateStats expires and stats are collected. This callback will contain the collected stats
[in]onStatsUpdateUserCookieA pointer to a user provided object. This object will be transferred to the onStatsUpdate callback each time it is called
Returns
True if capture started successfully, false if (relevant log error is printed in any case):
  • Capture is already running
  • Device is not opened
  • Stats collection thread could not be created

Reimplemented in pcpp::WinPcapLiveDevice.

◆ startCapture() [4/4]

virtual bool pcpp::PcapLiveDevice::startCapture ( RawPacketVector capturedPacketsVector)
virtual

Start capturing packets on this network interface (device). All captured packets are added to capturedPacketsVector, so at the end of the capture (when calling stopCapture()) this vector contains pointers to all captured packets in the form of RawPacket. The capture is done on a new thread created by this method, meaning capturedPacketsVector is updated from another thread other than the caller thread (so user should avoid changing or iterating this vector while capture is on). Capture process will stop and this capture thread will be terminated when calling stopCapture(). This method must be called after the device is opened (i.e the open() method was called), otherwise an error will be returned.

Parameters
[in]capturedPacketsVectorA reference to a RawPacketVector, meaning a vector of pointer to RawPacket objects
Returns
True if capture started successfully, false if (relevant log error is printed in any case):
  • Capture is already running
  • Device is not opened
  • Capture thread could not be created

Reimplemented in pcpp::WinPcapLiveDevice.

◆ startCaptureBlockingMode()

virtual int pcpp::PcapLiveDevice::startCaptureBlockingMode ( OnPacketArrivesStopBlocking  onPacketArrives,
void *  userCookie,
int  timeout 
)
virtual

Start capturing packets on this network interface (device) in blocking mode, meaning this method blocks and won't return until the user frees the blocking (via onPacketArrives callback) or until a user defined timeout expires. Whenever a packets is captured the onPacketArrives callback is called and lets the user handle the packet. In each callback call the user should return true if he wants to release the block or false if it wants it to keep blocking. Regardless of this callback a timeout is defined when start capturing. When this timeout expires the method will return.
Please notice that stopCapture() isn't needed here because when the method returns (after timeout or per user decision) capturing on the device is stopped

Parameters
[in]onPacketArrivesA callback given by the user for handling incoming packets. After handling each packet the user needs to return a boolean value. True value indicates stop capturing and stop blocking and false value indicates continue capturing and blocking
[in]userCookieA pointer to a user provided object. This object will be transferred to the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that give context to the capture callback, for example: objects that counts packets, manages flow state or manages the application state according to the packet that was captured
[in]timeoutA timeout in seconds for the blocking to stop even if the user didn't return "true" in the onPacketArrives callback If this timeout is set to 0 or less the timeout will be ignored, meaning the method will keep blocking until the user frees it via the onPacketArrives callback
Returns
-1 if timeout expired, 1 if blocking was stopped via onPacketArrives callback or 0 if an error occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log

◆ stopCapture()

void pcpp::PcapLiveDevice::stopCapture ( )

Stop a currently running packet capture. This method terminates gracefully both packet capture thread and periodic stats collection thread (both if exist)