Skip to content
Merged
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
9 changes: 9 additions & 0 deletions Packet++/header/NullLoopbackLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,14 @@ namespace pcpp
{
return OsiModelDataLinkLayer;
}

/// @brief Check if the data passes minimal validity checks for Null/Loopback layer
/// @param data A pointer to the data
/// @param dataLen Size of the data in bytes
/// @return True if the data can represent a valid Null/Loopback layer, false otherwise
bool static isDataValid(const uint8_t* data, size_t dataLen)
{
return data != nullptr && dataLen >= sizeof(uint32_t);
}
};
} // namespace pcpp
101 changes: 52 additions & 49 deletions Packet++/src/Packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,87 +739,90 @@ namespace pcpp

const uint8_t* rawData = m_RawPacket->getRawData();

if (linkType == LINKTYPE_ETHERNET)
switch (linkType)
{
case LinkLayerType::LINKTYPE_ETHERNET:
{
if (EthLayer::isDataValid(rawData, rawDataLen))
{
return new EthLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
else if (EthDot3Layer::isDataValid(rawData, rawDataLen))
if (EthDot3Layer::isDataValid(rawData, rawDataLen))
{
return new EthDot3Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
else
{
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
break;
}
else if (linkType == LINKTYPE_LINUX_SLL)
case LinkLayerType::LINKTYPE_LINUX_SLL:
{
return new SllLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
else if (linkType == LINKTYPE_LINUX_SLL2 && Sll2Layer::isDataValid(rawData, rawDataLen))
case LinkLayerType::LINKTYPE_LINUX_SLL2:
{
return new Sll2Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
if (Sll2Layer::isDataValid(rawData, rawDataLen))
{
return new Sll2Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
break;
}
else if (linkType == LINKTYPE_NULL)
case LinkLayerType::LINKTYPE_NULL:
{
if (rawDataLen >= sizeof(uint32_t))
if (NullLoopbackLayer::isDataValid(rawData, rawDataLen))
{
return new NullLoopbackLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
else // rawDataLen is too small fir Null/Loopback
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
break;
}
else if (linkType == LINKTYPE_RAW || linkType == LINKTYPE_DLT_RAW1 || linkType == LINKTYPE_DLT_RAW2)
case LinkLayerType::LINKTYPE_RAW:
case LinkLayerType::LINKTYPE_DLT_RAW1:
case LinkLayerType::LINKTYPE_DLT_RAW2:
{
uint8_t ipVer = rawData[0] & 0xf0;
if (ipVer == 0x40)
if (ipVer == 0x40 && IPv4Layer::isDataValid(rawData, rawDataLen))
{
return IPv4Layer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(
new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
return new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
else if (ipVer == 0x60)
if (ipVer == 0x60 && IPv6Layer::isDataValid(rawData, rawDataLen))
{
return IPv6Layer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(
new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
return new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
else
break;
}
case LinkLayerType::LINKTYPE_IPV4:
{
if (IPv4Layer::isDataValid(rawData, rawDataLen))
{
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
return new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
break;
}
else if (linkType == LINKTYPE_IPV4)
case LinkLayerType::LINKTYPE_IPV6:
{
return IPv4Layer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
if (IPv6Layer::isDataValid(rawData, rawDataLen))
{
return new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
}
break;
}
else if (linkType == LINKTYPE_IPV6)
case LinkLayerType::LINKTYPE_NFLOG:
{
return IPv6Layer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
if (NflogLayer::isDataValid(rawData, rawDataLen))
{
return new NflogLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
break;
}
else if (linkType == LINKTYPE_NFLOG)
case LinkLayerType::LINKTYPE_C_HDLC:
{
return NflogLayer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(new NflogLayer(const_cast<uint8_t*>(rawData), rawDataLen, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
if (CiscoHdlcLayer::isDataValid(rawData, rawDataLen))
{
return new CiscoHdlcLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
}
break;
}
else if (linkType == LINKTYPE_C_HDLC)
{
return CiscoHdlcLayer::isDataValid(rawData, rawDataLen)
? static_cast<Layer*>(new CiscoHdlcLayer(const_cast<uint8_t*>(rawData), rawDataLen, this))
: static_cast<Layer*>(
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
default:
// For all other link types, we don't have a specific layer. Just break and create a PayloadLayer
break;
}

// unknown link type
Expand Down
Loading