PcapPlusPlus  20.08+
pcpp::RawSocketDevice Class Reference

#include <RawSocketDevice.h>

Inheritance diagram for pcpp::RawSocketDevice:
pcpp::IDevice

Public Types

enum  RecvPacketResult { RecvSuccess = 0, RecvTimeout = 1, RecvWouldBlock = 2, RecvError = 3 }
 

Public Member Functions

 ~RawSocketDevice ()
 
RecvPacketResult receivePacket (RawPacket &rawPacket, bool blocking=true, int timeout=-1)
 
int receivePackets (RawPacketVector &packetVec, int timeout, int &failedRecv)
 
bool sendPacket (const RawPacket *rawPacket)
 
int sendPackets (const RawPacketVector &packetVec)
 
virtual bool open ()
 
virtual void close ()
 
- Public Member Functions inherited from pcpp::IDevice
bool isOpened ()
 

Detailed Description

A class that wraps the raw socket functionality. A raw socket is a network socket that allows direct sending and receiving of IP packets without any protocol-specific transport layer formatting (taken from Wikipedia: https://en.wikipedia.org/wiki/Network_socket#Raw_socket). This wrapper class enables creation of a raw socket, binding it to a network interface, and then receiving and sending packets on it. Current implementation supports only Windows and Linux because other platforms provide poor support for raw sockets making them practically unusable. There are also major differences between Linux and Windows in raw socket implementation, let's mention some of the:

  • On Windows administrative privileges are required for raw sockets creation, meaning the process running the code has to have these privileges. In Linux 'sudo' is required
  • On Windows raw sockets are implemented in L3, meaning the L2 (Ethernet) layer is omitted by the socket and only L3 and up are visible to the user. On Linux raw sockets are implemented on L2, meaning all layers (including the Ethernet data) are visible to the user.
  • On Windows sending packets is not supported, a raw socket can only receive packets. On Linux both send and receive are supported
  • Linux doesn't require binding to a specific network interface for receiving packets, but it does require binding for sending packets. Windows requires binding for receiving packets. For the sake of keeping a unified and simple cross-platform interface this class requires binding for both Linux and Windows, on both send and receive

More details about opening the raw socket, receiving and sending packets are explained in the corresponding class methods. Raw sockets are supported for both IPv4 and IPv6, so you can create and bind raw sockets to each of the two. Also, there is no limit on the number of sockets opened for a specific IP address or network interface, so you can create multiple instances of this class and bind all of them to the same interface and IP address.

Member Enumeration Documentation

◆ RecvPacketResult

An enum for reporting packet receive results

Enumerator
RecvSuccess 

Receive success

RecvTimeout 

Receive timeout - timeout expired without any packets being captured

RecvWouldBlock 

Receive would block - in non-blocking mode if there are no packets in the rx queue the receive method will return immediately with this return value

RecvError 

Receive error, usually will be followed by an error log

Constructor & Destructor Documentation

◆ ~RawSocketDevice()

pcpp::RawSocketDevice::~RawSocketDevice ( )

A d'tor for this class. It closes the raw socket if not previously closed by calling close()

Member Function Documentation

◆ close()

virtual void pcpp::RawSocketDevice::close ( )
virtual

Close the raw socket

Implements pcpp::IDevice.

◆ open()

virtual bool pcpp::RawSocketDevice::open ( )
virtual

Open the device by creating a raw socket and binding it to the network interface specified in the c'tor

Returns
True if device was opened successfully, false otherwise with a corresponding error log message

Implements pcpp::IDevice.

◆ receivePacket()

RecvPacketResult pcpp::RawSocketDevice::receivePacket ( RawPacket rawPacket,
bool  blocking = true,
int  timeout = -1 
)

Receive a packet on the raw socket. This method has several modes of operation:

  • Blocking/non-blocking - in blocking mode the method will not return until a packet is received on the socket or until the timeout expires. In non-blocking mode it will return immediately and in case no packets are on the receive queue RawSocketDevice::RecvWouldBlock will be returned. Unless specified otherwise, the default value is blocking mode
  • Receive timeout - in blocking mode, the user can set a timeout to wait until a packet is received. If the timeout expires and no packets were received, the method will return RawSocketDevice::RecvTimeout. The default value is a negative value which means no timeout

There is a slight difference on this method's behavior between Windows and Linux around how packets are received. On Linux the received packet contains all layers starting from the L2 (Ethernet). However on Windows raw socket are integrated in L3 level so the received packet contains only L3 (IP) layer and up.

Parameters
[out]rawPacketAn empty packet instance where the received packet data will be written to
[in]blockingIndicates whether to run in blocking or non-blocking mode. Default value is blocking
[in]timeoutWhen in blocking mode, specifies the timeout [in seconds] to wait for a packet. If timeout expired and no packets were captured the method will return RawSocketDevice::RecvTimeout. Zero or negative values mean no timeout. The default value is no timeout
Returns
The method returns one on the following values:

◆ receivePackets()

int pcpp::RawSocketDevice::receivePackets ( RawPacketVector packetVec,
int  timeout,
int &  failedRecv 
)

Receive packets into a packet vector for a certain amount of time. This method starts a timer and invokes the receivePacket() method in blocking mode repeatedly until the timeout expires. All packets received successfully are put into a packet vector

Parameters
[out]packetVecThe packet vector to add the received packet to
[in]timeoutTimeout in seconds to receive packets on the raw socket
[out]failedRecvNumber of receive attempts that failed
Returns
The number of packets received successfully

◆ sendPacket()

bool pcpp::RawSocketDevice::sendPacket ( const RawPacket rawPacket)

Send an Ethernet packet to the network. L2 protocols other than Ethernet are not supported in raw sockets. The entire packet is sent as is, including the original Ethernet and IP data. This method is only supported in Linux as Windows doesn't allow sending packets from raw sockets. Using it from other platforms will also return "false" with a corresponding error log message

Parameters
[in]rawPacketThe packet to send
Returns
True if packet was sent successfully or false if the socket is not open, if the packet is not Ethernet or if there was a failure sending the packet

◆ sendPackets()

int pcpp::RawSocketDevice::sendPackets ( const RawPacketVector packetVec)

Send a set of Ethernet packets to the network. L2 protocols other than Ethernet are not supported by raw sockets. The entire packet is sent as is, including the original Ethernet and IP data. This method is only supported in Linux as Windows doesn't allow sending packets from raw sockets. Using it from other platforms will return "false" with an appropriate error log message

Parameters
[in]packetVecThe set of packets to send
Returns
The number of packets sent successfully. For packets that weren't sent successfully there will be a corresponding error message printed to log