Skip to content

Commit 722ace3

Browse files
authored
Cleanup of Packet::createFirstLayer (#1981)
* Refactor if else chain to a switch case. * Refactor branches to only return on successful parse. Failed parses are left to be handled by the tail PayloadHeader, instead of being duplicated. * Fix warnings about default case. * Removed else. * Moved null loopback validity check to isDataValid.
1 parent eb6f909 commit 722ace3

File tree

2 files changed

+61
-49
lines changed

2 files changed

+61
-49
lines changed

Packet++/header/NullLoopbackLayer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,14 @@ namespace pcpp
7878
{
7979
return OsiModelDataLinkLayer;
8080
}
81+
82+
/// @brief Check if the data passes minimal validity checks for Null/Loopback layer
83+
/// @param data A pointer to the data
84+
/// @param dataLen Size of the data in bytes
85+
/// @return True if the data can represent a valid Null/Loopback layer, false otherwise
86+
bool static isDataValid(const uint8_t* data, size_t dataLen)
87+
{
88+
return data != nullptr && dataLen >= sizeof(uint32_t);
89+
}
8190
};
8291
} // namespace pcpp

Packet++/src/Packet.cpp

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -739,87 +739,90 @@ namespace pcpp
739739

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

742-
if (linkType == LINKTYPE_ETHERNET)
742+
switch (linkType)
743+
{
744+
case LinkLayerType::LINKTYPE_ETHERNET:
743745
{
744746
if (EthLayer::isDataValid(rawData, rawDataLen))
745747
{
746748
return new EthLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
747749
}
748-
else if (EthDot3Layer::isDataValid(rawData, rawDataLen))
750+
if (EthDot3Layer::isDataValid(rawData, rawDataLen))
749751
{
750752
return new EthDot3Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
751753
}
752-
else
753-
{
754-
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
755-
}
754+
break;
756755
}
757-
else if (linkType == LINKTYPE_LINUX_SLL)
756+
case LinkLayerType::LINKTYPE_LINUX_SLL:
758757
{
759758
return new SllLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
760759
}
761-
else if (linkType == LINKTYPE_LINUX_SLL2 && Sll2Layer::isDataValid(rawData, rawDataLen))
760+
case LinkLayerType::LINKTYPE_LINUX_SLL2:
762761
{
763-
return new Sll2Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
762+
if (Sll2Layer::isDataValid(rawData, rawDataLen))
763+
{
764+
return new Sll2Layer(const_cast<uint8_t*>(rawData), rawDataLen, this);
765+
}
766+
break;
764767
}
765-
else if (linkType == LINKTYPE_NULL)
768+
case LinkLayerType::LINKTYPE_NULL:
766769
{
767-
if (rawDataLen >= sizeof(uint32_t))
770+
if (NullLoopbackLayer::isDataValid(rawData, rawDataLen))
771+
{
768772
return new NullLoopbackLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
769-
else // rawDataLen is too small fir Null/Loopback
770-
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
773+
}
774+
break;
771775
}
772-
else if (linkType == LINKTYPE_RAW || linkType == LINKTYPE_DLT_RAW1 || linkType == LINKTYPE_DLT_RAW2)
776+
case LinkLayerType::LINKTYPE_RAW:
777+
case LinkLayerType::LINKTYPE_DLT_RAW1:
778+
case LinkLayerType::LINKTYPE_DLT_RAW2:
773779
{
774780
uint8_t ipVer = rawData[0] & 0xf0;
775-
if (ipVer == 0x40)
781+
if (ipVer == 0x40 && IPv4Layer::isDataValid(rawData, rawDataLen))
776782
{
777-
return IPv4Layer::isDataValid(rawData, rawDataLen)
778-
? static_cast<Layer*>(
779-
new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
780-
: static_cast<Layer*>(
781-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
783+
return new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
782784
}
783-
else if (ipVer == 0x60)
785+
if (ipVer == 0x60 && IPv6Layer::isDataValid(rawData, rawDataLen))
784786
{
785-
return IPv6Layer::isDataValid(rawData, rawDataLen)
786-
? static_cast<Layer*>(
787-
new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
788-
: static_cast<Layer*>(
789-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
787+
return new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
790788
}
791-
else
789+
break;
790+
}
791+
case LinkLayerType::LINKTYPE_IPV4:
792+
{
793+
if (IPv4Layer::isDataValid(rawData, rawDataLen))
792794
{
793-
return new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
795+
return new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
794796
}
797+
break;
795798
}
796-
else if (linkType == LINKTYPE_IPV4)
799+
case LinkLayerType::LINKTYPE_IPV6:
797800
{
798-
return IPv4Layer::isDataValid(rawData, rawDataLen)
799-
? static_cast<Layer*>(new IPv4Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
800-
: static_cast<Layer*>(
801-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
801+
if (IPv6Layer::isDataValid(rawData, rawDataLen))
802+
{
803+
return new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this);
804+
}
805+
break;
802806
}
803-
else if (linkType == LINKTYPE_IPV6)
807+
case LinkLayerType::LINKTYPE_NFLOG:
804808
{
805-
return IPv6Layer::isDataValid(rawData, rawDataLen)
806-
? static_cast<Layer*>(new IPv6Layer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this))
807-
: static_cast<Layer*>(
808-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
809+
if (NflogLayer::isDataValid(rawData, rawDataLen))
810+
{
811+
return new NflogLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
812+
}
813+
break;
809814
}
810-
else if (linkType == LINKTYPE_NFLOG)
815+
case LinkLayerType::LINKTYPE_C_HDLC:
811816
{
812-
return NflogLayer::isDataValid(rawData, rawDataLen)
813-
? static_cast<Layer*>(new NflogLayer(const_cast<uint8_t*>(rawData), rawDataLen, this))
814-
: static_cast<Layer*>(
815-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
817+
if (CiscoHdlcLayer::isDataValid(rawData, rawDataLen))
818+
{
819+
return new CiscoHdlcLayer(const_cast<uint8_t*>(rawData), rawDataLen, this);
820+
}
821+
break;
816822
}
817-
else if (linkType == LINKTYPE_C_HDLC)
818-
{
819-
return CiscoHdlcLayer::isDataValid(rawData, rawDataLen)
820-
? static_cast<Layer*>(new CiscoHdlcLayer(const_cast<uint8_t*>(rawData), rawDataLen, this))
821-
: static_cast<Layer*>(
822-
new PayloadLayer(const_cast<uint8_t*>(rawData), rawDataLen, nullptr, this));
823+
default:
824+
// For all other link types, we don't have a specific layer. Just break and create a PayloadLayer
825+
break;
823826
}
824827

825828
// unknown link type

0 commit comments

Comments
 (0)