diff --git a/Packet++/header/Layer.h b/Packet++/header/Layer.h index eeb7eaa238..efda6f01c7 100644 --- a/Packet++/header/Layer.h +++ b/Packet++/header/Layer.h @@ -30,6 +30,59 @@ namespace pcpp class Packet; + namespace internal + { + /// @brief Holds information about a Layer's data and object ownership. + struct LayerAllocationInfo + { + /// @brief Pointer to the Packet this layer is attached to (if any). + /// + /// If the layer is attached to a Packet, the layer's memory span (data) is considered managed by the + /// Packet. The Packet is responsible for keeping the layer's memory span valid and updating it should it + /// become necessary as long as the layer is attached to it. + /// + /// In an event the Packet is destroyed, all of its attached layers's memory views are considered invalid. + /// Accessing layer data after the Packet is destroyed results in undefined behavior. + /// + /// If nullptr, the layer is not attached to any Packet and is considered unmanaged. + /// It also means the layer's memory span is considered owned by the layer itself and will be freed when + /// the layer is destroyed. + Packet* attachedPacket = nullptr; + + /// @brief Controls if the layer object is considered managed by the attached Packet + /// + /// If 'true', the Layer object is considered managed by the attached Packet and will be tracked and freed + /// by it + /// + /// If 'false', the Layer object is considered unmanaged and the user is responsible for freeing it. + /// This is commonly the case for layers created on the stack and attached to a Packet. + bool managedByPacket = false; + + /// @brief Sets the state of attachment to a specified Packet + /// @param packet Pointer to the Packet this layer is attached to (or nullptr if not attached to any Packet) + /// @param managed True if the layer object's lifetime is to be managed by the Packet, false otherwise + /// @param force If true, bypasses the check for existing attachment. Default is false. + /// @throws std::runtime_error if the layer is already attached to a Packet and 'force' is false + void attachPacket(Packet* packet, bool managed, bool force = false) + { + if (!force && attachedPacket != nullptr) + { + throw std::runtime_error("Layer is already attached to a Packet"); + } + + attachedPacket = packet; + managedByPacket = managed; + } + + /// @brief Clears the attachment to any Packet, resetting to unmanaged state. + void detach() + { + attachedPacket = nullptr; + managedByPacket = false; + } + }; + } // namespace internal + /// @class Layer /// Layer is the base class for all protocol layers. Each protocol supported in PcapPlusPlus has a class that /// inherits Layer. @@ -125,7 +178,7 @@ namespace pcpp /// by the layer itself bool isAllocatedToPacket() const { - return m_Packet != nullptr; + return m_AllocationInfo.attachedPacket != nullptr; } /// Copy the raw data of this layer to another array @@ -160,26 +213,40 @@ namespace pcpp protected: uint8_t* m_Data; size_t m_DataLen; - Packet* m_Packet; ProtocolType m_Protocol; Layer* m_NextLayer; Layer* m_PrevLayer; - bool m_IsAllocatedInPacket; - Layer() - : m_Data(nullptr), m_DataLen(0), m_Packet(nullptr), m_Protocol(UnknownProtocol), m_NextLayer(nullptr), - m_PrevLayer(nullptr), m_IsAllocatedInPacket(false) + private: + internal::LayerAllocationInfo m_AllocationInfo; + + protected: + Layer() : m_Data(nullptr), m_DataLen(0), m_Protocol(UnknownProtocol), m_NextLayer(nullptr), m_PrevLayer(nullptr) {} Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, ProtocolType protocol = UnknownProtocol) - : m_Data(data), m_DataLen(dataLen), m_Packet(packet), m_Protocol(protocol), m_NextLayer(nullptr), - m_PrevLayer(prevLayer), m_IsAllocatedInPacket(false) + : m_Data(data), m_DataLen(dataLen), m_Protocol(protocol), m_NextLayer(nullptr), m_PrevLayer(prevLayer), + m_AllocationInfo{ packet, false } {} // Copy c'tor Layer(const Layer& other); Layer& operator=(const Layer& other); + /// @brief Get a pointer to the Packet this layer is attached to (if any). + /// @return A pointer to the Packet this layer is attached to, or nullptr if the layer is not attached. + Packet* getAttachedPacket() + { + return m_AllocationInfo.attachedPacket; + } + + /// @brief Get a pointer to the Packet this layer is attached to (if any). + /// @return A const pointer to the Packet this layer is attached to, or nullptr if the layer is not attached. + Packet const* getAttachedPacket() const + { + return m_AllocationInfo.attachedPacket; + } + void setNextLayer(Layer* nextLayer) { m_NextLayer = nextLayer; diff --git a/Packet++/src/BgpLayer.cpp b/Packet++/src/BgpLayer.cpp index 4e5098ccec..9536adcdb7 100644 --- a/Packet++/src/BgpLayer.cpp +++ b/Packet++/src/BgpLayer.cpp @@ -87,7 +87,7 @@ namespace pcpp uint8_t* payload = m_Data + headerLen; size_t payloadLen = m_DataLen - headerLen; - m_NextLayer = BgpLayer::parseBgpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = BgpLayer::parseBgpLayer(payload, payloadLen, this, getAttachedPacket()); } std::string BgpLayer::toString() const @@ -120,10 +120,10 @@ namespace pcpp bool BgpLayer::extendLayer(int offsetInLayer, size_t numOfBytesToExtend) { - if (m_Packet != nullptr) + if (getAttachedPacket() != nullptr) { - int rawPacketLen = m_Packet->getRawPacket()->getRawDataLen(); - const uint8_t* rawPacketPtr = m_Packet->getRawPacket()->getRawData(); + int rawPacketLen = getAttachedPacket()->getRawPacket()->getRawDataLen(); + const uint8_t* rawPacketPtr = getAttachedPacket()->getRawPacket()->getRawData(); if (m_Data - rawPacketPtr + static_cast(offsetInLayer) > static_cast(rawPacketLen)) { @@ -143,10 +143,10 @@ namespace pcpp bool BgpLayer::shortenLayer(int offsetInLayer, size_t numOfBytesToShorten) { - if (m_Packet != nullptr) + if (getAttachedPacket() != nullptr) { - int rawPacketLen = m_Packet->getRawPacket()->getRawDataLen(); - const uint8_t* rawPacketPtr = m_Packet->getRawPacket()->getRawData(); + int rawPacketLen = getAttachedPacket()->getRawPacket()->getRawDataLen(); + const uint8_t* rawPacketPtr = getAttachedPacket()->getRawPacket()->getRawData(); if (m_Data - rawPacketPtr + static_cast(offsetInLayer) + static_cast(numOfBytesToShorten) > diff --git a/Packet++/src/CiscoHdlcLayer.cpp b/Packet++/src/CiscoHdlcLayer.cpp index 7fac1ae5cd..42e92463b3 100644 --- a/Packet++/src/CiscoHdlcLayer.cpp +++ b/Packet++/src/CiscoHdlcLayer.cpp @@ -55,20 +55,20 @@ namespace pcpp case CISCO_HDLC_TYPE_IP: { m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; } case CISCO_HDLC_TYPE_IPV6: { m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; } default: { - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } } diff --git a/Packet++/src/CotpLayer.cpp b/Packet++/src/CotpLayer.cpp index 1183df5f13..6c5b47d435 100644 --- a/Packet++/src/CotpLayer.cpp +++ b/Packet++/src/CotpLayer.cpp @@ -73,8 +73,8 @@ namespace pcpp size_t payloadLen = m_DataLen - headerLen; if (S7CommLayer::isDataValid(payload, payloadLen)) - m_NextLayer = new S7CommLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new S7CommLayer(payload, payloadLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } // namespace pcpp diff --git a/Packet++/src/DoIpLayer.cpp b/Packet++/src/DoIpLayer.cpp index 2944888109..f5992e16ab 100644 --- a/Packet++/src/DoIpLayer.cpp +++ b/Packet++/src/DoIpLayer.cpp @@ -396,7 +396,7 @@ namespace pcpp uint8_t* payload = m_Data + headerLen; size_t payloadLen = m_DataLen - headerLen; - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } } diff --git a/Packet++/src/EthDot3Layer.cpp b/Packet++/src/EthDot3Layer.cpp index 35d6d48b14..c58489505e 100644 --- a/Packet++/src/EthDot3Layer.cpp +++ b/Packet++/src/EthDot3Layer.cpp @@ -30,9 +30,9 @@ namespace pcpp size_t payloadLen = m_DataLen - sizeof(ether_dot3_header); if (LLCLayer::isDataValid(payload, payloadLen)) - m_NextLayer = new LLCLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new LLCLayer(payload, payloadLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } std::string EthDot3Layer::toString() const diff --git a/Packet++/src/EthLayer.cpp b/Packet++/src/EthLayer.cpp index 40954d3174..ba8052eff0 100644 --- a/Packet++/src/EthLayer.cpp +++ b/Packet++/src/EthLayer.cpp @@ -39,35 +39,37 @@ namespace pcpp switch (be16toh(hdr->etherType)) { case PCPP_ETHERTYPE_IP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PCPP_ETHERTYPE_IPV6: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PCPP_ETHERTYPE_ARP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PCPP_ETHERTYPE_VLAN: case PCPP_ETHERTYPE_IEEE_802_1AD: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PCPP_ETHERTYPE_PPPOES: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, + getAttachedPacket()); break; case PCPP_ETHERTYPE_PPPOED: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, + getAttachedPacket()); break; case PCPP_ETHERTYPE_MPLS: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PCPP_ETHERTYPE_WAKE_ON_LAN: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; } // If no next layer was constructed, assume it's a payload layer if (!hasNextLayer()) - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } void EthLayer::computeCalculateFields() diff --git a/Packet++/src/GreLayer.cpp b/Packet++/src/GreLayer.cpp index 2bf2868b47..0f2e82a7a2 100644 --- a/Packet++/src/GreLayer.cpp +++ b/Packet++/src/GreLayer.cpp @@ -206,41 +206,41 @@ namespace pcpp { case PCPP_ETHERTYPE_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_VLAN: - m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_MPLS: - m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_PPP: m_NextLayer = PPP_PPTPLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPP_PPTPLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new PPP_PPTPLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_ETHBRIDGE: if (EthLayer::isDataValid(payload, payloadLen)) { - m_NextLayer = new EthLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new EthLayer(payload, payloadLen, this, getAttachedPacket()); } else if (EthDot3Layer::isDataValid(payload, payloadLen)) { - m_NextLayer = new EthDot3Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new EthDot3Layer(payload, payloadLen, this, getAttachedPacket()); } else { - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } @@ -576,16 +576,16 @@ namespace pcpp { case PCPP_PPP_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_PPP_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } } diff --git a/Packet++/src/GtpLayer.cpp b/Packet++/src/GtpLayer.cpp index 97129b1418..1dfe3a1ad4 100644 --- a/Packet++/src/GtpLayer.cpp +++ b/Packet++/src/GtpLayer.cpp @@ -590,18 +590,18 @@ namespace pcpp if (subProto >= 0x45 && subProto <= 0x4e) { m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); } else if ((subProto & 0xf0) == 0x60) { m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); } else { - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } @@ -1315,11 +1315,11 @@ namespace pcpp if (getHeader()->piggybacking && GtpV2Layer::isDataValid(nextLayerData, nextLayerDataLen)) { - m_NextLayer = new GtpV2Layer(nextLayerData, nextLayerDataLen, this, m_Packet); + m_NextLayer = new GtpV2Layer(nextLayerData, nextLayerDataLen, this, getAttachedPacket()); } else { - m_NextLayer = new PayloadLayer(nextLayerData, nextLayerDataLen, this, m_Packet); + m_NextLayer = new PayloadLayer(nextLayerData, nextLayerDataLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/IPSecLayer.cpp b/Packet++/src/IPSecLayer.cpp index 5f26dc0468..2dcb74cc09 100644 --- a/Packet++/src/IPSecLayer.cpp +++ b/Packet++/src/IPSecLayer.cpp @@ -64,32 +64,32 @@ namespace pcpp { case PACKETPP_IPPROTO_UDP: m_NextLayer = UdpLayer::isDataValid(payload, payloadLen) - ? static_cast(new UdpLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new UdpLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_TCP: m_NextLayer = TcpLayer::isDataValid(payload, payloadLen) - ? static_cast(new TcpLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new TcpLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_IPIP: { uint8_t ipVersion = *payload >> 4; if (ipVersion == 4 && IPv4Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new IPv4Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new IPv4Layer(payload, payloadLen, this, getAttachedPacket()); else if (ipVersion == 6 && IPv6Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new IPv6Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new IPv6Layer(payload, payloadLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } case PACKETPP_IPPROTO_ESP: m_NextLayer = ESPLayer::isDataValid(payload, payloadLen) - ? static_cast(new ESPLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new ESPLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } @@ -118,7 +118,7 @@ namespace pcpp if (m_DataLen <= headerLen) return; - m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } std::string ESPLayer::toString() const diff --git a/Packet++/src/IPv4Layer.cpp b/Packet++/src/IPv4Layer.cpp index 4a09134b96..e494277225 100644 --- a/Packet++/src/IPv4Layer.cpp +++ b/Packet++/src/IPv4Layer.cpp @@ -259,20 +259,20 @@ namespace pcpp // TODO: assuming first fragment contains at least L4 header, what if it's not true? if (isFragment()) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); return; } switch (ipHdr->protocol) { case PACKETPP_IPPROTO_UDP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PACKETPP_IPPROTO_TCP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PACKETPP_IPPROTO_ICMP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PACKETPP_IPPROTO_IPIP: { @@ -280,13 +280,13 @@ namespace pcpp switch (IPLayer::getIPVersion(payload, payloadLen)) { case IPv4: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case IPv6: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; default: - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); break; } break; @@ -296,13 +296,13 @@ namespace pcpp switch (GreLayer::getGREVersion(payload, payloadLen)) { case GREv0: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case GREv1: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; default: - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); break; }; break; @@ -316,47 +316,50 @@ namespace pcpp switch (igmpVer) { case IGMPv1: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case IGMPv2: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case IGMPv3: { if (igmpQuery) - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, + getAttachedPacket()); else - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, + getAttachedPacket()); break; } default: - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); break; } break; } case PACKETPP_IPPROTO_AH: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, + getAttachedPacket()); break; case PACKETPP_IPPROTO_ESP: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PACKETPP_IPPROTO_IPV6: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case PACKETPP_IPPROTO_VRRP: { switch (VrrpLayer::getVersionFromData(payload, payloadLen)) { case VRRPv2: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet); + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket()); break; case VRRPv3: - tryConstructNextLayerWithFallback(payload, payloadLen, m_Packet, + tryConstructNextLayerWithFallback(payload, payloadLen, getAttachedPacket(), IPAddress::IPv4AddressType); break; default: - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); break; } break; @@ -365,7 +368,7 @@ namespace pcpp // If no next layer was constructed, assume it's a payload layer if (!hasNextLayer()) - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } void IPv4Layer::computeCalculateFields() diff --git a/Packet++/src/IPv6Layer.cpp b/Packet++/src/IPv6Layer.cpp index fb17d09051..5d8c9fb61f 100644 --- a/Packet++/src/IPv6Layer.cpp +++ b/Packet++/src/IPv6Layer.cpp @@ -208,7 +208,7 @@ namespace pcpp { if (m_LastExtension->getExtensionType() == IPv6Extension::IPv6Fragmentation) { - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); return; } @@ -223,62 +223,64 @@ namespace pcpp { case PACKETPP_IPPROTO_UDP: m_NextLayer = UdpLayer::isDataValid(payload, payloadLen) - ? static_cast(new UdpLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new UdpLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_TCP: m_NextLayer = TcpLayer::isDataValid(payload, payloadLen) - ? static_cast(new TcpLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new TcpLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_IPIP: { uint8_t ipVersion = *payload >> 4; if (ipVersion == 4 && IPv4Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new IPv4Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new IPv4Layer(payload, payloadLen, this, getAttachedPacket()); else if (ipVersion == 6 && IPv6Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new IPv6Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new IPv6Layer(payload, payloadLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } case PACKETPP_IPPROTO_GRE: { ProtocolType greVer = GreLayer::getGREVersion(payload, payloadLen); if (greVer == GREv0 && GREv0Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new GREv0Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new GREv0Layer(payload, payloadLen, this, getAttachedPacket()); else if (greVer == GREv1 && GREv1Layer::isDataValid(payload, payloadLen)) - m_NextLayer = new GREv1Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = new GREv1Layer(payload, payloadLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } case PACKETPP_IPPROTO_AH: - m_NextLayer = AuthenticationHeaderLayer::isDataValid(payload, payloadLen) - ? static_cast(new AuthenticationHeaderLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + AuthenticationHeaderLayer::isDataValid(payload, payloadLen) + ? static_cast(new AuthenticationHeaderLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_ESP: m_NextLayer = ESPLayer::isDataValid(payload, payloadLen) - ? static_cast(new ESPLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new ESPLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PACKETPP_IPPROTO_ICMPV6: { - m_NextLayer = IcmpV6Layer::parseIcmpV6Layer(payload, payloadLen, this, m_Packet); + m_NextLayer = IcmpV6Layer::parseIcmpV6Layer(payload, payloadLen, this, getAttachedPacket()); break; } case PACKETPP_IPPROTO_VRRP: { auto vrrpVer = VrrpLayer::getVersionFromData(payload, payloadLen); if (vrrpVer == VRRPv3) - m_NextLayer = new VrrpV3Layer(payload, payloadLen, this, m_Packet, IPAddress::IPv6AddressType); + m_NextLayer = + new VrrpV3Layer(payload, payloadLen, this, getAttachedPacket(), IPAddress::IPv6AddressType); else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); return; } } diff --git a/Packet++/src/IcmpLayer.cpp b/Packet++/src/IcmpLayer.cpp index 171560aaef..cc81cf57a6 100644 --- a/Packet++/src/IcmpLayer.cpp +++ b/Packet++/src/IcmpLayer.cpp @@ -48,9 +48,9 @@ namespace pcpp { // remove all layers after - if (m_Packet != nullptr) + if (getAttachedPacket() != nullptr) { - bool res = m_Packet->removeAllLayersAfter(this); + bool res = getAttachedPacket()->removeAllLayersAfter(this); if (!res) return false; } @@ -99,20 +99,20 @@ namespace pcpp bool IcmpLayer::setIpAndL4Layers(IPv4Layer* ipLayer, Layer* l4Layer) { - if (m_Packet == nullptr) + if (getAttachedPacket() == nullptr) { PCPP_LOG_ERROR("Cannot set ICMP data that involves IP and L4 layers on a layer not attached to a packet. " "Please add the ICMP layer to a packet and try again"); return false; } - if (ipLayer != nullptr && !m_Packet->addLayer(ipLayer)) + if (ipLayer != nullptr && !getAttachedPacket()->addLayer(ipLayer)) { PCPP_LOG_ERROR("Couldn't add IP layer to ICMP packet"); return false; } - if (l4Layer != nullptr && !m_Packet->addLayer(l4Layer)) + if (l4Layer != nullptr && !getAttachedPacket()->addLayer(l4Layer)) { PCPP_LOG_ERROR("Couldn't add L4 layer to ICMP packet"); return false; @@ -574,13 +574,13 @@ namespace pcpp case ICMP_PARAM_PROBLEM: // clang-format off m_NextLayer = IPv4Layer::isDataValid(m_Data + headerLen, m_DataLen - headerLen) - ? static_cast(new IPv4Layer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet)) - : static_cast(new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet)); + ? static_cast(new IPv4Layer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket())); // clang-format on return; default: if (m_DataLen > headerLen) - m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); return; } } diff --git a/Packet++/src/LLCLayer.cpp b/Packet++/src/LLCLayer.cpp index 5cfe5d84da..289f91f150 100644 --- a/Packet++/src/LLCLayer.cpp +++ b/Packet++/src/LLCLayer.cpp @@ -35,12 +35,12 @@ namespace pcpp if (hdr->dsap == 0x42 && hdr->ssap == 0x42 && StpLayer::isDataValid(payload, payloadLen)) { - m_NextLayer = StpLayer::parseStpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = StpLayer::parseStpLayer(payload, payloadLen, this, getAttachedPacket()); if (!m_NextLayer) - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); return; } - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } std::string LLCLayer::toString() const diff --git a/Packet++/src/Layer.cpp b/Packet++/src/Layer.cpp index 171855907c..9b8a4aaa30 100644 --- a/Packet++/src/Layer.cpp +++ b/Packet++/src/Layer.cpp @@ -14,9 +14,7 @@ namespace pcpp delete[] m_Data; } - Layer::Layer(const Layer& other) - : m_Packet(nullptr), m_Protocol(other.m_Protocol), m_NextLayer(nullptr), m_PrevLayer(nullptr), - m_IsAllocatedInPacket(false) + Layer::Layer(const Layer& other) : m_Protocol(other.m_Protocol), m_NextLayer(nullptr), m_PrevLayer(nullptr) { m_DataLen = other.getHeaderLen(); m_Data = new uint8_t[other.m_DataLen]; @@ -28,16 +26,18 @@ namespace pcpp if (this == &other) return *this; + // Should this really always delete m_Data? What if the layer is attached to a packet? if (m_Data != nullptr) delete[] m_Data; + // Reset allocation info as the layer is considered copied and not attached to any packet. + m_AllocationInfo = internal::LayerAllocationInfo{}; + m_DataLen = other.getHeaderLen(); - m_Packet = nullptr; m_Protocol = other.m_Protocol; m_NextLayer = nullptr; m_PrevLayer = nullptr; m_Data = new uint8_t[other.m_DataLen]; - m_IsAllocatedInPacket = false; memcpy(m_Data, other.m_Data, other.m_DataLen); return *this; @@ -61,7 +61,7 @@ namespace pcpp return false; } - if (m_Packet == nullptr) + if (getAttachedPacket() == nullptr) { if (static_cast(offsetInLayer) > m_DataLen) { @@ -77,7 +77,7 @@ namespace pcpp return true; } - return m_Packet->extendLayer(this, offsetInLayer, numOfBytesToExtend); + return getAttachedPacket()->extendLayer(this, offsetInLayer, numOfBytesToExtend); } bool Layer::shortenLayer(int offsetInLayer, size_t numOfBytesToShorten) @@ -94,7 +94,7 @@ namespace pcpp return false; } - if (m_Packet == nullptr) + if (getAttachedPacket() == nullptr) { if (static_cast(offsetInLayer) >= m_DataLen) { @@ -111,7 +111,7 @@ namespace pcpp return true; } - return m_Packet->shortenLayer(this, offsetInLayer, numOfBytesToShorten); + return getAttachedPacket()->shortenLayer(this, offsetInLayer, numOfBytesToShorten); } } // namespace pcpp diff --git a/Packet++/src/LdapLayer.cpp b/Packet++/src/LdapLayer.cpp index 6ac3d260a1..be70fb9f26 100644 --- a/Packet++/src/LdapLayer.cpp +++ b/Packet++/src/LdapLayer.cpp @@ -372,7 +372,7 @@ namespace pcpp uint8_t* payload = m_Data + headerLen; size_t payloadLen = m_DataLen - headerLen; - m_NextLayer = LdapLayer::parseLdapMessage(payload, payloadLen, this, m_Packet); + m_NextLayer = LdapLayer::parseLdapMessage(payload, payloadLen, this, getAttachedPacket()); } // endregion diff --git a/Packet++/src/MplsLayer.cpp b/Packet++/src/MplsLayer.cpp index fe57a68529..0efe2b9c81 100644 --- a/Packet++/src/MplsLayer.cpp +++ b/Packet++/src/MplsLayer.cpp @@ -112,7 +112,7 @@ namespace pcpp if (!isBottomOfStack()) { - m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket()); return; } @@ -121,16 +121,16 @@ namespace pcpp { case 4: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case 6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/NflogLayer.cpp b/Packet++/src/NflogLayer.cpp index 3dc6f94480..fb17990db2 100644 --- a/Packet++/src/NflogLayer.cpp +++ b/Packet++/src/NflogLayer.cpp @@ -58,16 +58,16 @@ namespace pcpp { case PCPP_WS_NFPROTO_IPV4: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_WS_NFPROTO_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/NullLoopbackLayer.cpp b/Packet++/src/NullLoopbackLayer.cpp index d3ea72a2cf..2f63ff7675 100644 --- a/Packet++/src/NullLoopbackLayer.cpp +++ b/Packet++/src/NullLoopbackLayer.cpp @@ -62,17 +62,19 @@ namespace pcpp switch (ethType) { case PCPP_ETHERTYPE_IP: - m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + IPv4Layer::isDataValid(payload, payloadLen) + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); return; case PCPP_ETHERTYPE_IPV6: - m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + IPv6Layer::isDataValid(payload, payloadLen) + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); return; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); return; } } @@ -81,18 +83,18 @@ namespace pcpp { case PCPP_BSD_AF_INET: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_BSD_AF_INET6_BSD: case PCPP_BSD_AF_INET6_FREEBSD: case PCPP_BSD_AF_INET6_DARWIN: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/PPPoELayer.cpp b/Packet++/src/PPPoELayer.cpp index f8d0e88388..2bc2f3c609 100644 --- a/Packet++/src/PPPoELayer.cpp +++ b/Packet++/src/PPPoELayer.cpp @@ -53,16 +53,16 @@ namespace pcpp { case PCPP_PPP_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_PPP_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); break; } } diff --git a/Packet++/src/Packet.cpp b/Packet++/src/Packet.cpp index 8ff97f5a66..4e49892b6b 100644 --- a/Packet++/src/Packet.cpp +++ b/Packet++/src/Packet.cpp @@ -69,7 +69,7 @@ namespace pcpp for (auto* curLayer = m_FirstLayer; curLayer != nullptr; curLayer = curLayer->getNextLayer()) { // Mark the current layer as allocated in the packet - curLayer->m_IsAllocatedInPacket = true; + curLayer->m_AllocationInfo.managedByPacket = true; m_LastLayer = curLayer; // Update last layer to current layer // If the current layer is of a higher OSI layer than the target, stop parsing @@ -119,7 +119,7 @@ namespace pcpp new PacketTrailerLayer(static_cast(m_LastLayer->getData() + m_LastLayer->getDataLen()), trailerLen, m_LastLayer, this); - trailerLayer->m_IsAllocatedInPacket = true; + trailerLayer->m_AllocationInfo.managedByPacket = true; m_LastLayer->setNextLayer(trailerLayer); m_LastLayer = trailerLayer; } @@ -165,7 +165,7 @@ namespace pcpp while (curLayer != nullptr) { Layer* nextLayer = curLayer->getNextLayer(); - if (curLayer->m_IsAllocatedInPacket) + if (curLayer->m_AllocationInfo.managedByPacket) delete curLayer; curLayer = nextLayer; } @@ -197,7 +197,7 @@ namespace pcpp while (curLayer != nullptr) { curLayer->parseNextLayer(); - curLayer->m_IsAllocatedInPacket = true; + curLayer->m_AllocationInfo.managedByPacket = true; curLayer = curLayer->getNextLayer(); if (curLayer != nullptr) m_LastLayer = curLayer; @@ -294,12 +294,8 @@ namespace pcpp else newLayer->getNextLayer()->setPrevLayer(newLayer); - // assign layer with this packet only - newLayer->m_Packet = this; - - // Set flag to indicate if new layer is allocated to packet. - if (ownInPacket) - newLayer->m_IsAllocatedInPacket = true; + // Attach the layer to this packet. If ownInPacket is true, transfer ownership of the layer to the packet. + newLayer->m_AllocationInfo.attachPacket(this, ownInPacket); // re-calculate all layers data ptr and data length @@ -497,7 +493,7 @@ namespace pcpp } // if layer was allocated by this packet and tryToDelete flag is set, delete it - if (tryToDelete && layer->m_IsAllocatedInPacket) + if (tryToDelete && layer->m_AllocationInfo.managedByPacket) { delete layer; } @@ -505,7 +501,7 @@ namespace pcpp // be reused else { - layer->m_Packet = nullptr; + layer->m_AllocationInfo.detach(); layer->m_Data = layerOldData.release(); layer->m_DataLen = layerOldDataSize; } @@ -567,7 +563,7 @@ namespace pcpp } // verify layer is allocated to this packet - if (!(layer->m_Packet == this)) + if (!(layer->getAttachedPacket() == this)) { PCPP_LOG_ERROR("Layer isn't allocated to this packet"); return false; @@ -640,7 +636,7 @@ namespace pcpp } // verify layer is allocated to this packet - if (!(layer->m_Packet == this)) + if (!(layer->getAttachedPacket() == this)) { PCPP_LOG_ERROR("Layer isn't allocated to this packet"); return false; diff --git a/Packet++/src/SSHLayer.cpp b/Packet++/src/SSHLayer.cpp index 7181cf6f6d..2b6878ba9c 100644 --- a/Packet++/src/SSHLayer.cpp +++ b/Packet++/src/SSHLayer.cpp @@ -33,7 +33,7 @@ namespace pcpp size_t headerLen = getHeaderLen(); if (m_DataLen <= headerLen) return; - m_NextLayer = SSHLayer::createSSHMessage(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = SSHLayer::createSSHMessage(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } // -------------------------------- diff --git a/Packet++/src/SSLLayer.cpp b/Packet++/src/SSLLayer.cpp index e83b789c07..561733491b 100644 --- a/Packet++/src/SSLLayer.cpp +++ b/Packet++/src/SSLLayer.cpp @@ -95,7 +95,8 @@ namespace pcpp return; if (SSLLayer::IsSSLMessage(0, 0, m_Data + headerLen, m_DataLen - headerLen, true)) - m_NextLayer = SSLLayer::createSSLMessage(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = + SSLLayer::createSSLMessage(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } // ------------------------- diff --git a/Packet++/src/SipLayer.cpp b/Packet++/src/SipLayer.cpp index ac9acb1289..179ec8bff0 100644 --- a/Packet++/src/SipLayer.cpp +++ b/Packet++/src/SipLayer.cpp @@ -80,11 +80,11 @@ namespace pcpp if (contentType.find("application/sdp") != std::string::npos) { - m_NextLayer = new SdpLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = new SdpLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } else { - m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/Sll2Layer.cpp b/Packet++/src/Sll2Layer.cpp index 8bcbd3cedd..f8b0432c03 100644 --- a/Packet++/src/Sll2Layer.cpp +++ b/Packet++/src/Sll2Layer.cpp @@ -69,36 +69,38 @@ namespace pcpp { case PCPP_ETHERTYPE_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_ARP: - m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new ArpLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_VLAN: case PCPP_ETHERTYPE_IEEE_802_1AD: - m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_PPPOES: - m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoESessionLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_PPPOED: - m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_MPLS: - m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket()); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/SllLayer.cpp b/Packet++/src/SllLayer.cpp index 9e2141f9c1..2456696e81 100644 --- a/Packet++/src/SllLayer.cpp +++ b/Packet++/src/SllLayer.cpp @@ -61,36 +61,38 @@ namespace pcpp { case PCPP_ETHERTYPE_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_ARP: - m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new ArpLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_VLAN: case PCPP_ETHERTYPE_IEEE_802_1AD: - m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_PPPOES: - m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoESessionLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_PPPOED: - m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_MPLS: - m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket()); break; default: - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } diff --git a/Packet++/src/SomeIpLayer.cpp b/Packet++/src/SomeIpLayer.cpp index baf8a06e7b..fce86318d2 100644 --- a/Packet++/src/SomeIpLayer.cpp +++ b/Packet++/src/SomeIpLayer.cpp @@ -264,7 +264,7 @@ namespace pcpp uint8_t* payload = m_Data + headerLen; size_t payloadLen = m_DataLen - headerLen; - m_NextLayer = parseSomeIpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = parseSomeIpLayer(payload, payloadLen, this, getAttachedPacket()); } std::string SomeIpLayer::toString() const diff --git a/Packet++/src/StpLayer.cpp b/Packet++/src/StpLayer.cpp index 0eda516624..401af26840 100644 --- a/Packet++/src/StpLayer.cpp +++ b/Packet++/src/StpLayer.cpp @@ -82,7 +82,7 @@ namespace pcpp void StpTopologyChangeBPDULayer::parseNextLayer() { if (m_DataLen > sizeof(stp_tcn_bpdu)) - m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(stp_tcn_bpdu), this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(stp_tcn_bpdu), this, getAttachedPacket()); } // ---------------------- Class StpConfigurationBPDULayer ---------------------- @@ -227,7 +227,7 @@ namespace pcpp void StpConfigurationBPDULayer::parseNextLayer() { if (m_DataLen > sizeof(stp_conf_bpdu)) - m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(stp_conf_bpdu), this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(stp_conf_bpdu), this, getAttachedPacket()); } // ---------------------- Class RapidStpLayer ---------------------- @@ -242,7 +242,7 @@ namespace pcpp void RapidStpLayer::parseNextLayer() { if (m_DataLen > sizeof(rstp_conf_bpdu)) - m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(rstp_conf_bpdu), this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data, m_DataLen - sizeof(rstp_conf_bpdu), this, getAttachedPacket()); } // ---------------------- Class MultipleStpLayer ---------------------- diff --git a/Packet++/src/TcpLayer.cpp b/Packet++/src/TcpLayer.cpp index 0250b5e7b0..f3628f85cb 100644 --- a/Packet++/src/TcpLayer.cpp +++ b/Packet++/src/TcpLayer.cpp @@ -371,107 +371,107 @@ namespace pcpp if (HttpMessage::isHttpPort(portDst) && HttpRequestFirstLine::parseMethod(payloadChar, payloadLen) != HttpRequestLayer::HttpMethodUnknown) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (HttpMessage::isHttpPort(portSrc) && HttpResponseFirstLine::parseVersion(payloadChar, payloadLen) != HttpVersion::HttpVersionUnknown && !HttpResponseFirstLine::parseStatusCode(payloadChar, payloadLen).isUnsupportedCode()) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SSLLayer::IsSSLMessage(portSrc, portDst, payload, payloadLen)) { - setNextLayer(SSLLayer::createSSLMessage(payload, payloadLen, this, m_Packet)); + setNextLayer(SSLLayer::createSSLMessage(payload, payloadLen, this, getAttachedPacket())); } else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc)) { if (SipRequestFirstLine::parseMethod(payloadChar, payloadLen) != SipRequestLayer::SipMethodUnknown) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SipResponseFirstLine::parseStatusCode(payloadChar, payloadLen) != SipResponseLayer::SipStatusCodeUnknown) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } } else if (BgpLayer::isBgpPort(portSrc, portDst)) { - m_NextLayer = BgpLayer::parseBgpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = BgpLayer::parseBgpLayer(payload, payloadLen, this, getAttachedPacket()); if (!m_NextLayer) - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SSHLayer::isSSHPort(portSrc, portDst)) { - setNextLayer(SSHLayer::createSSHMessage(payload, payloadLen, this, m_Packet)); + setNextLayer(SSHLayer::createSSHMessage(payload, payloadLen, this, getAttachedPacket())); } else if (DnsLayer::isDataValid(payload, payloadLen, true) && (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc))) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (TelnetLayer::isDataValid(payload, payloadLen) && (TelnetLayer::isTelnetPort(portDst) || TelnetLayer::isTelnetPort(portSrc))) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (FtpLayer::isFtpPort(portSrc) && FtpLayer::isDataValid(payload, payloadLen)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (FtpLayer::isFtpPort(portDst) && FtpLayer::isDataValid(payload, payloadLen)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (FtpLayer::isFtpDataPort(portSrc) || FtpLayer::isFtpDataPort(portDst)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if ((DoIpLayer::isDoIpPort(portSrc) || DoIpLayer::isDoIpPort(portDst)) && (DoIpLayer::isDataValid(payload, payloadLen))) { - m_NextLayer = DoIpLayer::parseDoIpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = DoIpLayer::parseDoIpLayer(payload, payloadLen, this, getAttachedPacket()); if (!m_NextLayer) - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst)) { - setNextLayer(SomeIpLayer::parseSomeIpLayer(payload, payloadLen, this, m_Packet)); + setNextLayer(SomeIpLayer::parseSomeIpLayer(payload, payloadLen, this, getAttachedPacket())); } else if (TpktLayer::isDataValid(payload, payloadLen) && TpktLayer::isTpktPort(portSrc, portDst)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SmtpLayer::isSmtpPort(portSrc) && SmtpLayer::isDataValid(payload, payloadLen)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (SmtpLayer::isSmtpPort(portDst) && SmtpLayer::isDataValid(payload, payloadLen)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (LdapLayer::isLdapPort(portDst) || LdapLayer::isLdapPort(portSrc)) { - m_NextLayer = LdapLayer::parseLdapMessage(payload, payloadLen, this, m_Packet); + m_NextLayer = LdapLayer::parseLdapMessage(payload, payloadLen, this, getAttachedPacket()); if (!m_NextLayer) - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) && GtpV2Layer::isDataValid(payload, payloadLen)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else if (ModbusLayer::isModbusPort(portDst)) { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } else { - constructNextLayer(payload, payloadLen, m_Packet); + constructNextLayer(payload, payloadLen, getAttachedPacket()); } } diff --git a/Packet++/src/TextBasedProtocol.cpp b/Packet++/src/TextBasedProtocol.cpp index 1d35996384..d51cd2607a 100644 --- a/Packet++/src/TextBasedProtocol.cpp +++ b/Packet++/src/TextBasedProtocol.cpp @@ -409,7 +409,7 @@ namespace pcpp if (m_DataLen <= headerLen) return; - m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, m_Packet); + m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()); } size_t TextBasedProtocolMessage::getHeaderLen() const diff --git a/Packet++/src/TpktLayer.cpp b/Packet++/src/TpktLayer.cpp index c3fe3a9ff7..d401791757 100644 --- a/Packet++/src/TpktLayer.cpp +++ b/Packet++/src/TpktLayer.cpp @@ -65,10 +65,10 @@ namespace pcpp if (CotpLayer::isDataValid(payload, payloadLen)) { - m_NextLayer = new CotpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new CotpLayer(payload, payloadLen, this, getAttachedPacket()); } else - m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket()); } } // namespace pcpp diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp index 478d2893a3..d7cc1985c6 100644 --- a/Packet++/src/UdpLayer.cpp +++ b/Packet++/src/UdpLayer.cpp @@ -102,58 +102,58 @@ namespace pcpp size_t udpDataLen = m_DataLen - sizeof(udphdr); if (DhcpLayer::isDhcpPorts(portSrc, portDst)) - m_NextLayer = new DhcpLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new DhcpLayer(udpData, udpDataLen, this, getAttachedPacket()); else if (VxlanLayer::isVxlanPort(portDst)) - m_NextLayer = new VxlanLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new VxlanLayer(udpData, udpDataLen, this, getAttachedPacket()); else if (DnsLayer::isDataValid(udpData, udpDataLen) && (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc))) - m_NextLayer = new DnsLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new DnsLayer(udpData, udpDataLen, this, getAttachedPacket()); else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc)) { if (SipRequestFirstLine::parseMethod((char*)udpData, udpDataLen) != SipRequestLayer::SipMethodUnknown) - m_NextLayer = new SipRequestLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new SipRequestLayer(udpData, udpDataLen, this, getAttachedPacket()); else if (SipResponseFirstLine::parseStatusCode((char*)udpData, udpDataLen) != SipResponseLayer::SipStatusCodeUnknown && SipResponseFirstLine::parseVersion((char*)udpData, udpDataLen) != "") - m_NextLayer = new SipResponseLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new SipResponseLayer(udpData, udpDataLen, this, getAttachedPacket()); else - m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, getAttachedPacket()); } else if ((RadiusLayer::isRadiusPort(portDst) || RadiusLayer::isRadiusPort(portSrc)) && RadiusLayer::isDataValid(udpData, udpDataLen)) - m_NextLayer = new RadiusLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new RadiusLayer(udpData, udpDataLen, this, getAttachedPacket()); else if ((GtpV1Layer::isGTPv1Port(portDst) || GtpV1Layer::isGTPv1Port(portSrc)) && GtpV1Layer::isGTPv1(udpData, udpDataLen)) - m_NextLayer = new GtpV1Layer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new GtpV1Layer(udpData, udpDataLen, this, getAttachedPacket()); else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) && GtpV2Layer::isDataValid(udpData, udpDataLen)) - m_NextLayer = new GtpV2Layer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new GtpV2Layer(udpData, udpDataLen, this, getAttachedPacket()); else if ((DhcpV6Layer::isDhcpV6Port(portSrc) || DhcpV6Layer::isDhcpV6Port(portDst)) && (DhcpV6Layer::isDataValid(udpData, udpDataLen))) - m_NextLayer = new DhcpV6Layer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new DhcpV6Layer(udpData, udpDataLen, this, getAttachedPacket()); else if ((NtpLayer::isNTPPort(portSrc) || NtpLayer::isNTPPort(portDst)) && NtpLayer::isDataValid(udpData, udpDataLen)) - m_NextLayer = new NtpLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new NtpLayer(udpData, udpDataLen, this, getAttachedPacket()); else if ((DoIpLayer::isDoIpPort(portSrc) || DoIpLayer::isDoIpPort(portDst)) && (DoIpLayer::isDataValid(udpData, udpDataLen))) { - m_NextLayer = DoIpLayer::parseDoIpLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = DoIpLayer::parseDoIpLayer(udpData, udpDataLen, this, getAttachedPacket()); if (!m_NextLayer) - constructNextLayer(udpData, udpDataLen, m_Packet); + constructNextLayer(udpData, udpDataLen, getAttachedPacket()); } else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst)) - m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, getAttachedPacket()); else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) - m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, getAttachedPacket()); else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) && WireGuardLayer::isDataValid(udpData, udpDataLen))) { - m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, getAttachedPacket()); if (!m_NextLayer) - m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, getAttachedPacket()); } else - m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); + m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, getAttachedPacket()); } void UdpLayer::computeCalculateFields() diff --git a/Packet++/src/VlanLayer.cpp b/Packet++/src/VlanLayer.cpp index f12ca798ae..9ef82e803d 100644 --- a/Packet++/src/VlanLayer.cpp +++ b/Packet++/src/VlanLayer.cpp @@ -72,38 +72,40 @@ namespace pcpp { case PCPP_ETHERTYPE_IP: m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv4Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv4Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_IPV6: m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen) - ? static_cast(new IPv6Layer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new IPv6Layer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_ARP: - m_NextLayer = new ArpLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new ArpLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_VLAN: case PCPP_ETHERTYPE_IEEE_802_1AD: - m_NextLayer = new VlanLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket()); break; case PCPP_ETHERTYPE_PPPOES: - m_NextLayer = PPPoESessionLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoESessionLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoESessionLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_PPPOED: - m_NextLayer = PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) - ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + m_NextLayer = + PPPoEDiscoveryLayer::isDataValid(payload, payloadLen) + ? static_cast(new PPPoEDiscoveryLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); break; case PCPP_ETHERTYPE_MPLS: - m_NextLayer = new MplsLayer(payload, payloadLen, this, m_Packet); + m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket()); break; default: m_NextLayer = (be16toh(hdr->etherType) < 1500 && LLCLayer::isDataValid(payload, payloadLen)) - ? static_cast(new LLCLayer(payload, payloadLen, this, m_Packet)) - : static_cast(new PayloadLayer(payload, payloadLen, this, m_Packet)); + ? static_cast(new LLCLayer(payload, payloadLen, this, getAttachedPacket())) + : static_cast(new PayloadLayer(payload, payloadLen, this, getAttachedPacket())); } } diff --git a/Packet++/src/VrrpLayer.cpp b/Packet++/src/VrrpLayer.cpp index 664c9f1843..9816079aab 100644 --- a/Packet++/src/VrrpLayer.cpp +++ b/Packet++/src/VrrpLayer.cpp @@ -476,7 +476,7 @@ namespace pcpp uint16_t VrrpV3Layer::calculateChecksum() const { - auto* ipLayer = m_Packet->getLayerOfType(); + auto* ipLayer = getAttachedPacket()->getLayerOfType(); if (ipLayer == nullptr) { PCPP_LOG_ERROR("Calculate checksum failed, for can not get IPLayer" << ""); diff --git a/Packet++/src/VxlanLayer.cpp b/Packet++/src/VxlanLayer.cpp index 6001b4197b..14f781cbe4 100644 --- a/Packet++/src/VxlanLayer.cpp +++ b/Packet++/src/VxlanLayer.cpp @@ -54,7 +54,8 @@ namespace pcpp if (m_DataLen <= sizeof(vxlan_header)) return; - m_NextLayer = new EthLayer(m_Data + sizeof(vxlan_header), m_DataLen - sizeof(vxlan_header), this, m_Packet); + m_NextLayer = + new EthLayer(m_Data + sizeof(vxlan_header), m_DataLen - sizeof(vxlan_header), this, getAttachedPacket()); } } // namespace pcpp diff --git a/Tests/Packet++Test/Tests/PacketTests.cpp b/Tests/Packet++Test/Tests/PacketTests.cpp index ae53f5c60f..71b105025b 100644 --- a/Tests/Packet++Test/Tests/PacketTests.cpp +++ b/Tests/Packet++Test/Tests/PacketTests.cpp @@ -327,9 +327,9 @@ PTF_TEST_CASE(RemoveLayerTest) PTF_ASSERT_NULL(vxlanPacketOrig.getLayerOfType(pcpp::ICMP)); pcpp::Packet packetWithoutTunnel; - PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanEthLayer)); - PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIP4Layer)); - PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIcmpLayer)); + PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanEthLayer, true)); + PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIP4Layer, true)); + PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIcmpLayer, true)); packetWithoutTunnel.computeCalculateFields(); auto resource4 = pcpp_tests::loadHexResourceToVector("PacketExamples/IcmpWithoutTunnel.dat");