Coverage Report

Created: 2026-02-26 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/RawPacket.cpp
Line
Count
Source
1
0
#define LOG_MODULE PacketLogModuleRawPacket
2
3
#include "RawPacket.h"
4
#include "Logger.h"
5
#include "TimespecTimeval.h"
6
#include <cstring>
7
8
namespace pcpp
9
{
10
  RawPacket::RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool takeOwnership,
11
                       LinkLayerType layerType)
12
0
      : RawPacket(pRawData, rawDataLen, internal::toTimespec(timestamp), takeOwnership, layerType)
13
0
  {}
14
15
  RawPacket::RawPacket(const uint8_t* pRawData, int rawDataLen, timespec timestamp, bool takeOwnership,
16
                       LinkLayerType layerType)
17
0
      : m_RawData(const_cast<uint8_t*>(pRawData)), m_RawDataLen(rawDataLen), m_FrameLength(rawDataLen),
18
0
        m_TimeStamp(timestamp), m_OwnsRawData(takeOwnership), m_RawPacketSet(true), m_LinkLayerType(layerType)
19
0
  {}
20
21
  RawPacket::~RawPacket()
22
631
  {
23
631
    clear();
24
631
  }
25
26
  RawPacket::RawPacket(const RawPacket& other)
27
0
  {
28
0
    m_RawData = nullptr;
29
0
    copyDataFrom(other, true);
30
0
  }
31
32
  RawPacket& RawPacket::operator=(const RawPacket& other)
33
0
  {
34
0
    if (this != &other)
35
0
    {
36
0
      clear();
37
38
0
      copyDataFrom(other, true);
39
0
    }
40
41
0
    return *this;
42
0
  }
43
44
  RawPacket* RawPacket::clone() const
45
0
  {
46
0
    return new RawPacket(*this);
47
0
  }
48
49
  void RawPacket::copyDataFrom(const RawPacket& other, bool allocateData)
50
0
  {
51
0
    if (!other.m_RawPacketSet)
52
0
      return;
53
54
0
    m_TimeStamp = other.m_TimeStamp;
55
56
0
    if (allocateData)
57
0
    {
58
0
      m_OwnsRawData = true;
59
0
      m_RawData = new uint8_t[other.m_RawDataLen];
60
0
      m_RawDataLen = other.m_RawDataLen;
61
0
    }
62
63
0
    memcpy(m_RawData, other.m_RawData, other.m_RawDataLen);
64
0
    m_LinkLayerType = other.m_LinkLayerType;
65
0
    m_FrameLength = other.m_FrameLength;
66
0
    m_RawPacketSet = true;
67
0
  }
68
69
  bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, timeval timestamp, LinkLayerType layerType,
70
                             int frameLength)
71
0
  {
72
0
    DISABLE_WARNING_PUSH;
73
0
    DISABLE_WARNING_DEPRECATED;
74
75
0
    return setRawData(pRawData, rawDataLen, internal::toTimespec(timestamp), layerType, frameLength);
76
77
0
    DISABLE_WARNING_POP;
78
0
  }
79
80
  bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timeval timestamp,
81
                             LinkLayerType layerType, int frameLength)
82
0
  {
83
0
    return setRawData(pRawData, rawDataLen, takeOwnership, internal::toTimespec(timestamp), layerType, frameLength);
84
0
  }
85
86
  bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp, LinkLayerType layerType,
87
                             int frameLength)
88
0
  {
89
    // Legacy compatibility:
90
    //  In previous versions of this method inherited the old ownership value and used it for the new buffer.
91
    //  To keep backward compatibility we keep the same behavior here.
92
0
    return doSetRawData(pRawData, rawDataLen, m_OwnsRawData, timestamp, layerType, frameLength);
93
0
  }
94
95
  bool RawPacket::setRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timespec timestamp,
96
                             LinkLayerType layerType, int frameLength)
97
4.17k
  {
98
4.17k
    return doSetRawData(pRawData, rawDataLen, takeOwnership, timestamp, layerType, frameLength);
99
4.17k
  }
100
101
  bool RawPacket::doSetRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timespec timestamp,
102
                               LinkLayerType layerType, int frameLength)
103
4.17k
  {
104
4.17k
    clear();
105
106
4.17k
    m_OwnsRawData = takeOwnership;
107
4.17k
    m_FrameLength = (frameLength == -1) ? rawDataLen : frameLength;
108
4.17k
    m_RawData = (uint8_t*)pRawData;
109
4.17k
    m_RawDataLen = rawDataLen;
110
4.17k
    m_TimeStamp = timestamp;
111
4.17k
    m_RawPacketSet = true;
112
4.17k
    m_LinkLayerType = layerType;
113
4.17k
    return true;
114
4.17k
  }
115
116
  bool RawPacket::initWithRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp,
117
                                  LinkLayerType layerType)
118
0
  {
119
0
    return setRawData(pRawData, rawDataLen, false, timestamp, layerType);
120
0
  }
121
122
  void RawPacket::clear()
123
4.81k
  {
124
4.81k
    if (m_RawData != nullptr && m_OwnsRawData)
125
2.86k
      delete[] m_RawData;
126
127
4.81k
    m_RawData = nullptr;
128
4.81k
    m_RawDataLen = 0;
129
4.81k
    m_FrameLength = 0;
130
4.81k
    m_RawPacketSet = false;
131
4.81k
  }
132
133
  void RawPacket::appendData(const uint8_t* dataToAppend, size_t dataToAppendLen)
134
0
  {
135
0
    memcpy((uint8_t*)m_RawData + m_RawDataLen, dataToAppend, dataToAppendLen);
136
0
    m_RawDataLen += dataToAppendLen;
137
0
    m_FrameLength = m_RawDataLen;
138
0
  }
139
140
  void RawPacket::insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen)
141
0
  {
142
    // memmove copies data as if there was an intermediate buffer in between - so it allows for copying processes on
143
    // overlapping src/dest ptrs if insertData is called with atIndex == m_RawDataLen, then no data is being moved.
144
    // The data of the raw packet is still extended by dataToInsertLen
145
0
    memmove((uint8_t*)m_RawData + atIndex + dataToInsertLen, (uint8_t*)m_RawData + atIndex, m_RawDataLen - atIndex);
146
147
0
    if (dataToInsert != nullptr)
148
0
    {
149
      // insert data
150
0
      memcpy((uint8_t*)m_RawData + atIndex, dataToInsert, dataToInsertLen);
151
0
    }
152
153
0
    m_RawDataLen += dataToInsertLen;
154
0
    m_FrameLength = m_RawDataLen;
155
0
  }
156
157
  bool RawPacket::reallocateData(size_t newBufferLength)
158
0
  {
159
0
    if ((int)newBufferLength == m_RawDataLen)
160
0
      return true;
161
162
0
    if ((int)newBufferLength < m_RawDataLen)
163
0
    {
164
0
      PCPP_LOG_ERROR("Cannot reallocate raw packet to a smaller size. Current data length: "
165
0
                     << m_RawDataLen << "; requested length: " << newBufferLength);
166
0
      return false;
167
0
    }
168
169
0
    uint8_t* newBuffer = new uint8_t[newBufferLength];
170
0
    memset(newBuffer, 0, newBufferLength);
171
0
    memcpy(newBuffer, m_RawData, m_RawDataLen);
172
0
    if (m_OwnsRawData)
173
0
      delete[] m_RawData;
174
175
0
    m_OwnsRawData = true;
176
0
    m_RawData = newBuffer;
177
178
0
    return true;
179
0
  }
180
181
  bool RawPacket::removeData(int atIndex, size_t numOfBytesToRemove)
182
0
  {
183
0
    if ((atIndex + (int)numOfBytesToRemove) > m_RawDataLen)
184
0
    {
185
0
      PCPP_LOG_ERROR("Remove section is out of raw packet bound");
186
0
      return false;
187
0
    }
188
189
    // only move data if we are removing data somewhere in the layer, not at the end of the last layer
190
    // this is so that resizing of the last layer can occur fast by just reducing the fictional length of the packet
191
    // (m_RawDataLen) by the given amount
192
0
    if ((atIndex + (int)numOfBytesToRemove) != m_RawDataLen)
193
      // memmove copies data as if there was an intermediate buffer in between - so it allows for copying
194
      // processes on overlapping src/dest ptrs
195
0
      memmove((uint8_t*)m_RawData + atIndex, (uint8_t*)m_RawData + atIndex + numOfBytesToRemove,
196
0
              m_RawDataLen - (atIndex + numOfBytesToRemove));
197
198
0
    m_RawDataLen -= numOfBytesToRemove;
199
0
    m_FrameLength = m_RawDataLen;
200
0
    return true;
201
0
  }
202
203
  bool RawPacket::setPacketTimeStamp(timeval timestamp)
204
0
  {
205
0
    return setPacketTimeStamp(internal::toTimespec(timestamp));
206
0
  }
207
208
  bool RawPacket::setPacketTimeStamp(timespec timestamp)
209
0
  {
210
0
    m_TimeStamp = timestamp;
211
0
    return true;
212
0
  }
213
214
  bool RawPacket::isLinkTypeValid(int linkTypeValue)
215
0
  {
216
0
    if ((linkTypeValue < 0 || linkTypeValue > 264) && linkTypeValue != 276)
217
0
      return false;
218
219
0
    switch (static_cast<LinkLayerType>(linkTypeValue))
220
0
    {
221
0
    case LINKTYPE_ETHERNET:
222
0
    case LINKTYPE_LINUX_SLL:
223
0
    case LINKTYPE_RAW:
224
0
    case LINKTYPE_DLT_RAW1:
225
0
    case LINKTYPE_DLT_RAW2:
226
0
    case LINKTYPE_NULL:
227
0
    case LINKTYPE_AX25:
228
0
    case LINKTYPE_IEEE802_5:
229
0
    case LINKTYPE_ARCNET_BSD:
230
0
    case LINKTYPE_SLIP:
231
0
    case LINKTYPE_PPP:
232
0
    case LINKTYPE_FDDI:
233
0
    case LINKTYPE_PPP_HDLC:
234
0
    case LINKTYPE_PPP_ETHER:
235
0
    case LINKTYPE_ATM_RFC1483:
236
0
    case LINKTYPE_C_HDLC:
237
0
    case LINKTYPE_IEEE802_11:
238
0
    case LINKTYPE_FRELAY:
239
0
    case LINKTYPE_LOOP:
240
0
    case LINKTYPE_LTALK:
241
0
    case LINKTYPE_PFLOG:
242
0
    case LINKTYPE_IEEE802_11_PRISM:
243
0
    case LINKTYPE_IP_OVER_FC:
244
0
    case LINKTYPE_SUNATM:
245
0
    case LINKTYPE_IEEE802_11_RADIOTAP:
246
0
    case LINKTYPE_ARCNET_LINUX:
247
0
    case LINKTYPE_APPLE_IP_OVER_IEEE1394:
248
0
    case LINKTYPE_MTP2_WITH_PHDR:
249
0
    case LINKTYPE_MTP2:
250
0
    case LINKTYPE_MTP3:
251
0
    case LINKTYPE_SCCP:
252
0
    case LINKTYPE_DOCSIS:
253
0
    case LINKTYPE_LINUX_IRDA:
254
0
    case LINKTYPE_IEEE802_11_AVS:
255
0
    case LINKTYPE_BACNET_MS_TP:
256
0
    case LINKTYPE_PPP_PPPD:
257
0
    case LINKTYPE_GPRS_LLC:
258
0
    case LINKTYPE_GPF_T:
259
0
    case LINKTYPE_GPF_F:
260
0
    case LINKTYPE_LINUX_LAPD:
261
0
    case LINKTYPE_BLUETOOTH_HCI_H4:
262
0
    case LINKTYPE_USB_LINUX:
263
0
    case LINKTYPE_PPI:
264
0
    case LINKTYPE_IEEE802_15_4:
265
0
    case LINKTYPE_SITA:
266
0
    case LINKTYPE_ERF:
267
0
    case LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR:
268
0
    case LINKTYPE_AX25_KISS:
269
0
    case LINKTYPE_LAPD:
270
0
    case LINKTYPE_PPP_WITH_DIR:
271
0
    case LINKTYPE_C_HDLC_WITH_DIR:
272
0
    case LINKTYPE_FRELAY_WITH_DIR:
273
0
    case LINKTYPE_IPMB_LINUX:
274
0
    case LINKTYPE_IEEE802_15_4_NONASK_PHY:
275
0
    case LINKTYPE_USB_LINUX_MMAPPED:
276
0
    case LINKTYPE_FC_2:
277
0
    case LINKTYPE_FC_2_WITH_FRAME_DELIMS:
278
0
    case LINKTYPE_IPNET:
279
0
    case LINKTYPE_CAN_SOCKETCAN:
280
0
    case LINKTYPE_IPV4:
281
0
    case LINKTYPE_IPV6:
282
0
    case LINKTYPE_IEEE802_15_4_NOFCS:
283
0
    case LINKTYPE_DBUS:
284
0
    case LINKTYPE_DVB_CI:
285
0
    case LINKTYPE_MUX27010:
286
0
    case LINKTYPE_STANAG_5066_D_PDU:
287
0
    case LINKTYPE_NFLOG:
288
0
    case LINKTYPE_NETANALYZER:
289
0
    case LINKTYPE_NETANALYZER_TRANSPARENT:
290
0
    case LINKTYPE_IPOIB:
291
0
    case LINKTYPE_MPEG_2_TS:
292
0
    case LINKTYPE_NG40:
293
0
    case LINKTYPE_NFC_LLCP:
294
0
    case LINKTYPE_INFINIBAND:
295
0
    case LINKTYPE_SCTP:
296
0
    case LINKTYPE_USBPCAP:
297
0
    case LINKTYPE_RTAC_SERIAL:
298
0
    case LINKTYPE_BLUETOOTH_LE_LL:
299
0
    case LINKTYPE_NETLINK:
300
0
    case LINKTYPE_BLUETOOTH_LINUX_MONITOR:
301
0
    case LINKTYPE_BLUETOOTH_BREDR_BB:
302
0
    case LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR:
303
0
    case LINKTYPE_PROFIBUS_DL:
304
0
    case LINKTYPE_PKTAP:
305
0
    case LINKTYPE_EPON:
306
0
    case LINKTYPE_IPMI_HPM_2:
307
0
    case LINKTYPE_ZWAVE_R1_R2:
308
0
    case LINKTYPE_ZWAVE_R3:
309
0
    case LINKTYPE_WATTSTOPPER_DLM:
310
0
    case LINKTYPE_ISO_14443:
311
0
    case LINKTYPE_LINUX_SLL2:
312
0
      return true;
313
0
    default:
314
0
      return false;
315
0
    }
316
0
  }
317
318
}  // namespace pcpp