diff --git a/Packet++/header/NullLoopbackLayer.h b/Packet++/header/NullLoopbackLayer.h index 0903781771..6c0e2ec261 100644 --- a/Packet++/header/NullLoopbackLayer.h +++ b/Packet++/header/NullLoopbackLayer.h @@ -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 diff --git a/Packet++/src/Packet.cpp b/Packet++/src/Packet.cpp index a60ea2ce78..6826bac736 100644 --- a/Packet++/src/Packet.cpp +++ b/Packet++/src/Packet.cpp @@ -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(rawData), rawDataLen, this); } - else if (EthDot3Layer::isDataValid(rawData, rawDataLen)) + if (EthDot3Layer::isDataValid(rawData, rawDataLen)) { return new EthDot3Layer(const_cast(rawData), rawDataLen, this); } - else - { - return new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this); - } + break; } - else if (linkType == LINKTYPE_LINUX_SLL) + case LinkLayerType::LINKTYPE_LINUX_SLL: { return new SllLayer(const_cast(rawData), rawDataLen, this); } - else if (linkType == LINKTYPE_LINUX_SLL2 && Sll2Layer::isDataValid(rawData, rawDataLen)) + case LinkLayerType::LINKTYPE_LINUX_SLL2: { - return new Sll2Layer(const_cast(rawData), rawDataLen, this); + if (Sll2Layer::isDataValid(rawData, rawDataLen)) + { + return new Sll2Layer(const_cast(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(rawData), rawDataLen, this); - else // rawDataLen is too small fir Null/Loopback - return new PayloadLayer(const_cast(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( - new IPv4Layer(const_cast(rawData), rawDataLen, nullptr, this)) - : static_cast( - new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + return new IPv4Layer(const_cast(rawData), rawDataLen, nullptr, this); } - else if (ipVer == 0x60) + if (ipVer == 0x60 && IPv6Layer::isDataValid(rawData, rawDataLen)) { - return IPv6Layer::isDataValid(rawData, rawDataLen) - ? static_cast( - new IPv6Layer(const_cast(rawData), rawDataLen, nullptr, this)) - : static_cast( - new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + return new IPv6Layer(const_cast(rawData), rawDataLen, nullptr, this); } - else + break; + } + case LinkLayerType::LINKTYPE_IPV4: + { + if (IPv4Layer::isDataValid(rawData, rawDataLen)) { - return new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this); + return new IPv4Layer(const_cast(rawData), rawDataLen, nullptr, this); } + break; } - else if (linkType == LINKTYPE_IPV4) + case LinkLayerType::LINKTYPE_IPV6: { - return IPv4Layer::isDataValid(rawData, rawDataLen) - ? static_cast(new IPv4Layer(const_cast(rawData), rawDataLen, nullptr, this)) - : static_cast( - new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + if (IPv6Layer::isDataValid(rawData, rawDataLen)) + { + return new IPv6Layer(const_cast(rawData), rawDataLen, nullptr, this); + } + break; } - else if (linkType == LINKTYPE_IPV6) + case LinkLayerType::LINKTYPE_NFLOG: { - return IPv6Layer::isDataValid(rawData, rawDataLen) - ? static_cast(new IPv6Layer(const_cast(rawData), rawDataLen, nullptr, this)) - : static_cast( - new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + if (NflogLayer::isDataValid(rawData, rawDataLen)) + { + return new NflogLayer(const_cast(rawData), rawDataLen, this); + } + break; } - else if (linkType == LINKTYPE_NFLOG) + case LinkLayerType::LINKTYPE_C_HDLC: { - return NflogLayer::isDataValid(rawData, rawDataLen) - ? static_cast(new NflogLayer(const_cast(rawData), rawDataLen, this)) - : static_cast( - new PayloadLayer(const_cast(rawData), rawDataLen, nullptr, this)); + if (CiscoHdlcLayer::isDataValid(rawData, rawDataLen)) + { + return new CiscoHdlcLayer(const_cast(rawData), rawDataLen, this); + } + break; } - else if (linkType == LINKTYPE_C_HDLC) - { - return CiscoHdlcLayer::isDataValid(rawData, rawDataLen) - ? static_cast(new CiscoHdlcLayer(const_cast(rawData), rawDataLen, this)) - : static_cast( - new PayloadLayer(const_cast(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