Coverage Report

Created: 2026-09-28 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/Layer.cpp
Line
Count
Source
1
4.24k
#define LOG_MODULE PacketLogModuleLayer
2
3
#include "Layer.h"
4
#include "Logger.h"
5
#include "Packet.h"
6
#include <cstring>
7
#include <stdexcept>
8
9
namespace pcpp
10
{
11
12
  Layer::~Layer()
13
4.80M
  {
14
4.80M
    if (!isAllocatedToPacket())
15
113k
      delete[] m_Data;
16
4.80M
  }
17
18
113k
  Layer::Layer(const Layer& other) : m_Protocol(other.m_Protocol), m_NextLayer(nullptr), m_PrevLayer(nullptr)
19
113k
  {
20
113k
    m_DataLen = other.getHeaderLen();
21
113k
    m_Data = new uint8_t[other.m_DataLen];
22
113k
    memcpy(m_Data, other.m_Data, other.m_DataLen);
23
113k
  }
24
25
  Layer& Layer::operator=(const Layer& other)
26
11.3k
  {
27
11.3k
    if (this == &other)
28
0
      return *this;
29
30
    // Should this really always delete m_Data? What if the layer is attached to a packet?
31
11.3k
    if (m_Data != nullptr)
32
11.3k
      delete[] m_Data;
33
34
    // Reset allocation info as the layer is considered copied and not attached to any packet.
35
11.3k
    m_AllocationInfo = internal::LayerAllocationInfo{};
36
37
11.3k
    m_DataLen = other.getHeaderLen();
38
11.3k
    m_Protocol = other.m_Protocol;
39
11.3k
    m_NextLayer = nullptr;
40
11.3k
    m_PrevLayer = nullptr;
41
11.3k
    m_Data = new uint8_t[other.m_DataLen];
42
11.3k
    memcpy(m_Data, other.m_Data, other.m_DataLen);
43
44
11.3k
    return *this;
45
11.3k
  }
46
47
  bool Layer::isMemberOfProtocolFamily(ProtocolTypeFamily protocolTypeFamily) const
48
15.8M
  {
49
15.8M
    return m_Protocol != UnknownProtocol && internal::protoFamilyContainsProtocol(protocolTypeFamily, m_Protocol);
50
15.8M
  }
51
52
  void Layer::copyData(uint8_t* toArr) const
53
0
  {
54
0
    memcpy(toArr, m_Data, m_DataLen);
55
0
  }
56
57
  size_t Layer::copyData(uint8_t* dest, size_t destSize) const
58
0
  {
59
0
    size_t bytesToCopy = (std::min)(destSize, m_DataLen);
60
0
    memcpy(dest, m_Data, bytesToCopy);
61
0
    return bytesToCopy;
62
0
  }
63
64
  const FieldDescriptor Layer::SerializedFields::ProtocolName{ MaxID, "protocolName" };
65
  const FieldDescriptor Layer::SerializedFields::ProtocolId{ MaxID - 1, "protocolId" };
66
  const FieldDescriptor Layer::SerializedFields::Length{ MaxID, "length" };
67
  const FieldDescriptor LayerObject{ 0, "layer" };
68
69
  void Layer::serialize(ISerializer& serializer) const
70
0
  {
71
0
    auto layerObject = serializer.writeObject(LayerObject);
72
0
    layerObject.writeField(SerializedFields::ProtocolName, protocolTypeToString(m_Protocol));
73
0
    layerObject.writeField(SerializedFields::ProtocolId, m_Protocol);
74
0
    layerObject.writeField(SerializedFields::Length, getHeaderLen());
75
0
    serializeLayer(layerObject);
76
0
  }
77
78
  void Layer::allocData(size_t dataLen, bool zeroInit)
79
0
  {
80
0
    if (m_Data != nullptr)
81
0
    {
82
0
      throw std::runtime_error(
83
0
          "Layer already has allocated data. Use extendLayer or shortenLayer to modify the data length.");
84
0
    }
85
86
0
    if (m_AllocationInfo.attachedPacket != nullptr)
87
0
    {
88
      // TODO: Allocate the layer data through the attached packet
89
0
      throw std::logic_error("not implemented");
90
0
    }
91
92
0
    m_Data = new uint8_t[dataLen];
93
0
    m_DataLen = dataLen;
94
0
    if (zeroInit)
95
0
    {
96
0
      std::fill_n(m_Data, m_DataLen, 0);
97
0
    }
98
0
  }
99
100
  bool Layer::extendLayer(int offsetInLayer, size_t numOfBytesToExtend)
101
191k
  {
102
191k
    if (m_Data == nullptr)
103
0
    {
104
0
      PCPP_LOG_ERROR("Layer's data is nullptr");
105
0
      return false;
106
0
    }
107
108
191k
    if (getAttachedPacket() == nullptr)
109
113k
    {
110
113k
      if (static_cast<size_t>(offsetInLayer) > m_DataLen)
111
2.12k
      {
112
2.12k
        PCPP_LOG_ERROR("Requested offset is larger than data length");
113
2.12k
        return false;
114
2.12k
      }
115
111k
      uint8_t* newData = new uint8_t[m_DataLen + numOfBytesToExtend];
116
111k
      memcpy(newData, m_Data, offsetInLayer);
117
111k
      memcpy(newData + offsetInLayer + numOfBytesToExtend, m_Data + offsetInLayer, m_DataLen - offsetInLayer);
118
111k
      delete[] m_Data;
119
111k
      m_Data = newData;
120
111k
      m_DataLen += numOfBytesToExtend;
121
111k
      return true;
122
113k
    }
123
124
77.9k
    return getAttachedPacket()->extendLayer(this, offsetInLayer, numOfBytesToExtend);
125
191k
  }
126
127
  bool Layer::shortenLayer(int offsetInLayer, size_t numOfBytesToShorten)
128
78.2k
  {
129
78.2k
    if (m_Data == nullptr)
130
0
    {
131
0
      PCPP_LOG_ERROR("Layer's data is nullptr");
132
0
      return false;
133
0
    }
134
135
78.2k
    if (static_cast<size_t>(offsetInLayer) + numOfBytesToShorten > m_DataLen)
136
0
    {
137
0
      PCPP_LOG_ERROR("Requested number of bytes to shorten is larger than data length");
138
0
      return false;
139
0
    }
140
141
78.2k
    if (getAttachedPacket() == nullptr)
142
8.80k
    {
143
8.80k
      if (static_cast<size_t>(offsetInLayer) >= m_DataLen)
144
0
      {
145
0
        PCPP_LOG_ERROR("Requested offset is larger than data length");
146
0
        return false;
147
0
      }
148
8.80k
      uint8_t* newData = new uint8_t[m_DataLen - numOfBytesToShorten];
149
8.80k
      memcpy(newData, m_Data, offsetInLayer);
150
8.80k
      memcpy(newData + offsetInLayer, m_Data + offsetInLayer + numOfBytesToShorten,
151
8.80k
             m_DataLen - offsetInLayer - numOfBytesToShorten);
152
8.80k
      delete[] m_Data;
153
8.80k
      m_Data = newData;
154
8.80k
      m_DataLen -= numOfBytesToShorten;
155
8.80k
      return true;
156
8.80k
    }
157
158
69.4k
    return getAttachedPacket()->shortenLayer(this, offsetInLayer, numOfBytesToShorten);
159
78.2k
  }
160
161
}  // namespace pcpp