Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 85 additions & 26 deletions Packet++/header/RawPacket.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,102 @@ namespace pcpp
/// Max packet size supported
#define PCPP_MAX_PACKET_SIZE 65536

namespace internal
{
// TODO: Class is experimental and should not be used in user code yet. Eventually promote it to public API
/// @brief A base class for raw packet classes, containing common attributes and methods.
class RawPacketBase
{
protected:
/// @brief A default constructor that zero initializes the timestamp and sets the link layer type to
/// Ethernet.
RawPacketBase() = default;
/// @brief A constructor that initializes the timestamp and link layer type.
/// @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision)
/// @param[in] linkLayerType The link layer type of the packet, defaulting to Ethernet.
explicit RawPacketBase(timespec timestamp, LinkLayerType linkLayerType = LinkLayerType::LINKTYPE_ETHERNET);
/// @brief A constructor that initializes the timestamp and link layer type.
/// @param[in] timestamp The timestamp packet was received by the NIC (in usec precision)
/// @param[in] linkLayerType The link layer type of the packet, defaulting to Ethernet.
explicit RawPacketBase(timeval timestamp, LinkLayerType linkLayerType = LinkLayerType::LINKTYPE_ETHERNET);

// Copy and move constructors and assignment operators are protected to prevent slicing
RawPacketBase(const RawPacketBase&) = default;
RawPacketBase(RawPacketBase&&) = default;
RawPacketBase& operator=(const RawPacketBase&) = default;
RawPacketBase& operator=(RawPacketBase&&) = default;

public:
virtual ~RawPacketBase() = default;

/// @brief Get the link layer type of the packet.
/// @return A LinkLayerType enum value representing the link layer type of the packet.
LinkLayerType getLinkLayerType() const
{
return m_LinkLayerType;
}

/// @brief Return the timestamp of the packet.
/// @return The timestamp of the packet with nanosecond precision.
timespec getPacketTimeStamp() const
{
return m_TimeStamp;
}

/// Set raw packet timestamp with usec precision
/// @param[in] timestamp The timestamp to set (with usec precision)
/// @return True if timestamp was set successfully, false otherwise
bool setPacketTimeStamp(timeval timestamp);

/// Set raw packet timestamp with nsec precision
/// @param[in] timestamp The timestamp to set (with nsec precision)
/// @return True if timestamp was set successfully, false otherwise
bool setPacketTimeStamp(timespec timestamp);

// To be implemented in derived classes:

// bool isContiguous() const = 0; <- eventually needed for MBufRawPacket to indicate if the mbuf is a single
// segment or not.

// uint8_t* getRawData() = 0; <- maybe protected, so direct modification is not allowed? Expose maybe a span
// proxy instead for public?

// uint8_t const* getRawData() const = 0;

// int getRawDataLen() const = 0; <- should probably return size_t for consistency with modern C++
// practices, but the current API uses int

// Mutators:
// void setRawData(...) = 0;
// bool appendData(...) = 0;
// bool insertData(...) = 0;
// void removeData(...) = 0;
// void clear(...) = 0;

protected:
void setLinkLayerType(LinkLayerType linkLayerType)
{
m_LinkLayerType = linkLayerType;
}

private:
timespec m_TimeStamp{}; // Zero initialized
LinkLayerType m_LinkLayerType = LinkLayerType::LINKTYPE_ETHERNET;
};
} // namespace internal

/// @class RawPacket
/// This class holds the packet as raw (not parsed) data. The data is held as byte array. In addition to the data
/// itself every instance also holds a timestamp representing the time the packet was received by the NIC. RawPacket
/// instance isn't read only. The user can change the packet data, add or remove data, etc.
class RawPacket
class RawPacket : public internal::RawPacketBase
{
protected:
uint8_t* m_RawData = nullptr;
int m_RawDataLen = 0;
int m_FrameLength = 0;
timespec m_TimeStamp{}; // Zero initialized
bool m_DeleteRawDataAtDestructor = true;
bool m_RawPacketSet = false;
LinkLayerType m_LinkLayerType = LinkLayerType::LINKTYPE_ETHERNET;

void copyDataFrom(const RawPacket& other, bool allocateData = true);

Expand Down Expand Up @@ -372,13 +454,6 @@ namespace pcpp
return m_RawData;
}

/// Get the link layer type
/// @return the type of the link layer
LinkLayerType getLinkLayerType() const
{
return m_LinkLayerType;
}

/// This static method validates whether a link type integer value is valid
/// @param[in] linkTypeValue Link type integer value
/// @return True if the link type value is valid and can be casted into LinkLayerType enum, false otherwise
Expand All @@ -397,22 +472,6 @@ namespace pcpp
{
return m_FrameLength;
}
/// Get raw data timestamp
/// @return Raw data timestamp
timespec getPacketTimeStamp() const
{
return m_TimeStamp;
}

/// Set raw packet timestamp with usec precision
/// @param[in] timestamp The timestamp to set (with usec precision)
/// @return True if timestamp was set successfully, false otherwise
virtual bool setPacketTimeStamp(timeval timestamp);

/// Set raw packet timestamp with nsec precision
/// @param[in] timestamp The timestamp to set (with nsec precision)
/// @return True if timestamp was set successfully, false otherwise
virtual bool setPacketTimeStamp(timespec timestamp);

/// Get an indication whether raw data was already set for this instance.
/// @return True if raw data was set for this instance. Raw data can be set using the non-default constructor,
Expand Down
47 changes: 29 additions & 18 deletions Packet++/src/RawPacket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,38 @@

namespace pcpp
{
namespace internal
{
RawPacketBase::RawPacketBase(timespec timestamp, LinkLayerType linkLayerType)
: m_TimeStamp(timestamp), m_LinkLayerType(linkLayerType)
{}

RawPacketBase::RawPacketBase(timeval timestamp, LinkLayerType linkLayerType)
: m_TimeStamp(internal::toTimespec(timestamp)), m_LinkLayerType(linkLayerType)
{}

bool RawPacketBase::setPacketTimeStamp(timeval timestamp)
{
return setPacketTimeStamp(internal::toTimespec(timestamp));
}

bool RawPacketBase::setPacketTimeStamp(timespec timestamp)
{
m_TimeStamp = timestamp;
return true;
}
} // namespace internal

RawPacket::RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool deleteRawDataAtDestructor,
LinkLayerType layerType)
: RawPacket(pRawData, rawDataLen, internal::toTimespec(timestamp), deleteRawDataAtDestructor, layerType)
{}

RawPacket::RawPacket(const uint8_t* pRawData, int rawDataLen, timespec timestamp, bool deleteRawDataAtDestructor,
LinkLayerType layerType)
: m_RawData(const_cast<uint8_t*>(pRawData)), m_RawDataLen(rawDataLen), m_FrameLength(rawDataLen),
m_TimeStamp(timestamp), m_DeleteRawDataAtDestructor(deleteRawDataAtDestructor), m_RawPacketSet(true),
m_LinkLayerType(layerType)
: internal::RawPacketBase(timestamp, layerType), m_RawData(const_cast<uint8_t*>(pRawData)),
m_RawDataLen(rawDataLen), m_FrameLength(rawDataLen), m_DeleteRawDataAtDestructor(deleteRawDataAtDestructor),
m_RawPacketSet(true)
{}

RawPacket::~RawPacket()
Expand Down Expand Up @@ -52,7 +74,8 @@ namespace pcpp
if (!other.m_RawPacketSet)
return;

m_TimeStamp = other.m_TimeStamp;
// Call base class copy assignment operator to copy timestamp and link layer type
RawPacketBase::operator=(other);

if (allocateData)
{
Expand All @@ -62,7 +85,6 @@ namespace pcpp
}

memcpy(m_RawData, other.m_RawData, other.m_RawDataLen);
m_LinkLayerType = other.m_LinkLayerType;
m_FrameLength = other.m_FrameLength;
m_RawPacketSet = true;
}
Expand All @@ -81,9 +103,9 @@ namespace pcpp
m_FrameLength = (frameLength == -1) ? rawDataLen : frameLength;
m_RawData = (uint8_t*)pRawData;
m_RawDataLen = rawDataLen;
m_TimeStamp = timestamp;
setPacketTimeStamp(timestamp); // Always returns true
setLinkLayerType(layerType);
m_RawPacketSet = true;
m_LinkLayerType = layerType;
return true;
}

Expand Down Expand Up @@ -175,17 +197,6 @@ namespace pcpp
return true;
}

bool RawPacket::setPacketTimeStamp(timeval timestamp)
{
return setPacketTimeStamp(internal::toTimespec(timestamp));
}

bool RawPacket::setPacketTimeStamp(timespec timestamp)
{
m_TimeStamp = timestamp;
return true;
}

bool RawPacket::isLinkTypeValid(int linkTypeValue)
{
if ((linkTypeValue < 0 || linkTypeValue > 264) && linkTypeValue != 276)
Expand Down
6 changes: 3 additions & 3 deletions Pcap++/src/MBufRawPacket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ namespace pcpp
return;
}

setMBuf(newMbuf, other.m_TimeStamp);
setMBuf(newMbuf, other.getPacketTimeStamp());

m_RawPacketSet = false;

Expand Down Expand Up @@ -217,10 +217,10 @@ namespace pcpp
m_RawDataLen = rte_pktmbuf_pkt_len(m_MBuf);
memcpy(m_RawData, pRawData, m_RawDataLen);
delete[] pRawData;
m_TimeStamp = timestamp;
setPacketTimeStamp(timestamp);
m_RawPacketSet = true;
m_FrameLength = frameLength;
m_LinkLayerType = layerType;
setLinkLayerType(layerType);

return true;
}
Expand Down
Loading