Coverage Report

Created: 2026-09-28 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/RawPacket.h
Line
Count
Source
1
#pragma once
2
3
#include <stdint.h>
4
#include <stdexcept>
5
#ifdef _MSC_VER
6
# include <winsock2.h>
7
# include <time.h>
8
#else
9
# include <sys/time.h>
10
#endif
11
#include <stddef.h>
12
13
#include "DeprecationUtils.h"
14
15
/// @file
16
17
/// @namespace pcpp
18
/// @brief The main namespace for the PcapPlusPlus lib
19
namespace pcpp
20
{
21
  /// An enum describing all known link layer type. Taken from: http://www.tcpdump.org/linktypes.html .
22
  enum LinkLayerType
23
  {
24
    /// BSD loopback encapsulation
25
    LINKTYPE_NULL = 0,
26
    /// IEEE 802.3 Ethernet
27
    LINKTYPE_ETHERNET = 1,
28
    /// AX.25 packet
29
    LINKTYPE_AX25 = 3,
30
    /// IEEE 802.5 Token Ring
31
    LINKTYPE_IEEE802_5 = 6,
32
    /// ARCNET Data Packets
33
    LINKTYPE_ARCNET_BSD = 7,
34
    /// SLIP, encapsulated with a LINKTYPE_SLIP header
35
    LINKTYPE_SLIP = 8,
36
    /// PPP, as per RFC 1661 and RFC 1662
37
    LINKTYPE_PPP = 9,
38
    /// FDDI, as specified by ANSI INCITS 239-1994
39
    LINKTYPE_FDDI = 10,
40
    /// Raw IP
41
    LINKTYPE_DLT_RAW1 = 12,
42
    /// Raw IP (OpenBSD)
43
    LINKTYPE_DLT_RAW2 = 14,
44
    /// PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547
45
    LINKTYPE_PPP_HDLC = 50,
46
    /// PPPoE
47
    LINKTYPE_PPP_ETHER = 51,
48
    /// RFC 1483 LLC/SNAP-encapsulated ATM
49
    LINKTYPE_ATM_RFC1483 = 100,
50
    /// Raw IP
51
    LINKTYPE_RAW = 101,
52
    /// Cisco PPP with HDLC framing
53
    LINKTYPE_C_HDLC = 104,
54
    /// IEEE 802.11 wireless LAN
55
    LINKTYPE_IEEE802_11 = 105,
56
    /// Frame Relay
57
    LINKTYPE_FRELAY = 107,
58
    /// OpenBSD loopback encapsulation
59
    LINKTYPE_LOOP = 108,
60
    /// Linux "cooked" capture encapsulation
61
    LINKTYPE_LINUX_SLL = 113,
62
    /// Apple LocalTalk
63
    LINKTYPE_LTALK = 114,
64
    /// OpenBSD pflog
65
    LINKTYPE_PFLOG = 117,
66
    /// Prism monitor mode information followed by an 802.11 header
67
    LINKTYPE_IEEE802_11_PRISM = 119,
68
    /// RFC 2625 IP-over-Fibre Channel
69
    LINKTYPE_IP_OVER_FC = 122,
70
    /// ATM traffic, encapsulated as per the scheme used by SunATM devices
71
    LINKTYPE_SUNATM = 123,
72
    /// Radiotap link-layer information followed by an 802.11 header
73
    LINKTYPE_IEEE802_11_RADIOTAP = 127,
74
    /// ARCNET Data Packets, as described by the ARCNET Trade Association standard ATA 878.1-1999
75
    LINKTYPE_ARCNET_LINUX = 129,
76
    /// Apple IP-over-IEEE 1394 cooked header
77
    LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138,
78
    /// Signaling System 7 Message Transfer Part Level 2
79
    LINKTYPE_MTP2_WITH_PHDR = 139,
80
    /// Signaling System 7 Message Transfer Part Level 2
81
    LINKTYPE_MTP2 = 140,
82
    /// Signaling System 7 Message Transfer Part Level 3
83
    LINKTYPE_MTP3 = 141,
84
    /// Signaling System 7 Signalling Connection Control Part
85
    LINKTYPE_SCCP = 142,
86
    /// Signaling System 7 Signalling Connection Control Part
87
    LINKTYPE_DOCSIS = 143,
88
    /// Linux-IrDA packets
89
    LINKTYPE_LINUX_IRDA = 144,
90
    /// Reserved for private use
91
    LINKTYPE_USER0 = 147,
92
    /// Reserved for private use
93
    LINKTYPE_USER1 = 148,
94
    /// Reserved for private use
95
    LINKTYPE_USER2 = 149,
96
    /// Reserved for private use
97
    LINKTYPE_USER3 = 150,
98
    /// Reserved for private use
99
    LINKTYPE_USER4 = 151,
100
    /// Reserved for private use
101
    LINKTYPE_USER5 = 152,
102
    /// Reserved for private use
103
    LINKTYPE_USER6 = 153,
104
    /// Reserved for private use
105
    LINKTYPE_USER7 = 154,
106
    /// Reserved for private use
107
    LINKTYPE_USER8 = 155,
108
    /// Reserved for private use
109
    LINKTYPE_USER9 = 156,
110
    /// Reserved for private use
111
    LINKTYPE_USER10 = 157,
112
    /// Reserved for private use
113
    LINKTYPE_USER11 = 158,
114
    /// Reserved for private use
115
    LINKTYPE_USER12 = 159,
116
    /// Reserved for private use
117
    LINKTYPE_USER13 = 160,
118
    /// Reserved for private use
119
    LINKTYPE_USER14 = 161,
120
    /// Reserved for private use
121
    LINKTYPE_USER15 = 162,
122
    /// AVS monitor mode information followed by an 802.11 header
123
    LINKTYPE_IEEE802_11_AVS = 163,
124
    /// BACnet MS/TP frames
125
    LINKTYPE_BACNET_MS_TP = 165,
126
    /// PPP in HDLC-like encapsulation, like LINKTYPE_PPP_HDLC, but with the 0xff address byte replaced by a
127
    /// direction indication - 0x00 for incoming and 0x01 for outgoing
128
    LINKTYPE_PPP_PPPD = 166,
129
    /// General Packet Radio Service Logical Link Control
130
    LINKTYPE_GPRS_LLC = 169,
131
    /// Transparent-mapped generic framing procedure
132
    LINKTYPE_GPF_T = 170,
133
    /// Frame-mapped generic framing procedure
134
    LINKTYPE_GPF_F = 171,
135
    /// Link Access Procedures on the D Channel (LAPD) frames
136
    LINKTYPE_LINUX_LAPD = 177,
137
    /// Bluetooth HCI UART transport layer
138
    LINKTYPE_BLUETOOTH_HCI_H4 = 187,
139
    /// USB packets, beginning with a Linux USB header
140
    LINKTYPE_USB_LINUX = 189,
141
    /// Per-Packet Information information
142
    LINKTYPE_PPI = 192,
143
    /// IEEE 802.15.4 wireless Personal Area Network
144
    LINKTYPE_IEEE802_15_4 = 195,
145
    /// Various link-layer types, with a pseudo-header, for SITA
146
    LINKTYPE_SITA = 196,
147
    /// Various link-layer types, with a pseudo-header, for Endace DAG cards; encapsulates Endace ERF record
148
    LINKTYPE_ERF = 197,
149
    /// Bluetooth HCI UART transport layer
150
    LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201,
151
    /// AX.25 packet, with a 1-byte KISS header containing a type indicator
152
    LINKTYPE_AX25_KISS = 202,
153
    /// Link Access Procedures on the D Channel (LAPD) frames
154
    LINKTYPE_LAPD = 203,
155
    /// PPP, as per RFC 1661 and RFC 1662, preceded with a one-byte pseudo-header with a zero value meaning
156
    /// "received by this host" and a non-zero value meaning  "sent by this host"
157
    LINKTYPE_PPP_WITH_DIR = 204,
158
    /// Cisco PPP with HDLC framing
159
    LINKTYPE_C_HDLC_WITH_DIR = 205,
160
    /// Frame Relay
161
    LINKTYPE_FRELAY_WITH_DIR = 206,
162
    /// IPMB over an I2C circuit
163
    LINKTYPE_IPMB_LINUX = 209,
164
    /// IEEE 802.15.4 wireless Personal Area Network
165
    LINKTYPE_IEEE802_15_4_NONASK_PHY = 215,
166
    /// USB packets, beginning with a Linux USB header
167
    LINKTYPE_USB_LINUX_MMAPPED = 220,
168
    /// Fibre Channel FC-2 frames, beginning with a Frame_Header
169
    LINKTYPE_FC_2 = 224,
170
    /// Fibre Channel FC-2 frames
171
    LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225,
172
    /// Solaris ipnet pseudo-header
173
    LINKTYPE_IPNET = 226,
174
    /// CAN (Controller Area Network) frames, with a pseudo-header as supplied by Linux SocketCAN
175
    LINKTYPE_CAN_SOCKETCAN = 227,
176
    /// Raw IPv4; the packet begins with an IPv4 header
177
    LINKTYPE_IPV4 = 228,
178
    /// Raw IPv6; the packet begins with an IPv6 header
179
    LINKTYPE_IPV6 = 229,
180
    /// IEEE 802.15.4 wireless Personal Area Network, without the FCS at the end of the frame
181
    LINKTYPE_IEEE802_15_4_NOFCS = 230,
182
    /// Raw D-Bus messages, starting with the endianness flag, followed by the message type, etc., but without the
183
    /// authentication handshake before the message sequence
184
    LINKTYPE_DBUS = 231,
185
    /// DVB-CI (DVB Common Interface for communication between a PC Card module and a DVB receiver), with the
186
    /// message format specified by the PCAP format for DVB-CI specification
187
    LINKTYPE_DVB_CI = 235,
188
    /// Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but not the same as, 27.010)
189
    LINKTYPE_MUX27010 = 236,
190
    /// D_PDUs as described by NATO standard STANAG 5066, starting with the synchronization sequence, and including
191
    /// both header and data CRCs
192
    LINKTYPE_STANAG_5066_D_PDU = 237,
193
    /// Linux netlink NETLINK NFLOG socket log messages
194
    LINKTYPE_NFLOG = 239,
195
    /// Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an
196
    /// Ethernet frame, beginning with the MAC header and ending with the FCS
197
    LINKTYPE_NETANALYZER = 240,
198
    /// Pseudo-header for Hilscher Gesellschaft für Systemautomation mbH netANALYZER devices, followed by an
199
    /// Ethernet frame, beginning with the preamble, SFD, and MAC header, and ending with the FCS
200
    LINKTYPE_NETANALYZER_TRANSPARENT = 241,
201
    /// IP-over-InfiniBand, as specified by RFC 4391 section 6
202
    LINKTYPE_IPOIB = 242,
203
    /// MPEG-2 Transport Stream transport packets, as specified by ISO 13818-1/ITU-T Recommendation H.222.0
204
    LINKTYPE_MPEG_2_TS = 243,
205
    /// Pseudo-header for ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as used by their ng40
206
    /// protocol tester
207
    LINKTYPE_NG40 = 244,
208
    /// Pseudo-header for NFC LLCP packet captures, followed by frame data for the LLCP Protocol as specified by
209
    /// NFCForum-TS-LLCP_1.1
210
    LINKTYPE_NFC_LLCP = 245,
211
    /// Raw InfiniBand frames, starting with the Local Routing Header
212
    LINKTYPE_INFINIBAND = 247,
213
    /// SCTP packets, as defined by RFC 4960, with no lower-level protocols such as IPv4 or IPv6
214
    LINKTYPE_SCTP = 248,
215
    /// USB packets, beginning with a USBPcap header
216
    LINKTYPE_USBPCAP = 249,
217
    /// Serial-line packet header for the Schweitzer Engineering Laboratories "RTAC" product
218
    LINKTYPE_RTAC_SERIAL = 250,
219
    /// Bluetooth Low Energy air interface Link Layer packets
220
    LINKTYPE_BLUETOOTH_LE_LL = 251,
221
    /// Linux Netlink capture encapsulation
222
    LINKTYPE_NETLINK = 253,
223
    /// Bluetooth Linux Monitor encapsulation of traffic for the BlueZ stack
224
    LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254,
225
    /// Bluetooth Basic Rate and Enhanced Data Rate baseband packets
226
    LINKTYPE_BLUETOOTH_BREDR_BB = 255,
227
    /// Bluetooth Low Energy link-layer packets
228
    LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256,
229
    /// PROFIBUS data link layer packets, as specified by IEC standard 61158-6-3
230
    LINKTYPE_PROFIBUS_DL = 257,
231
    /// Apple PKTAP capture encapsulation
232
    LINKTYPE_PKTAP = 258,
233
    /// Ethernet-over-passive-optical-network packets
234
    LINKTYPE_EPON = 259,
235
    /// IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" in the PICMG HPM.2 specification
236
    LINKTYPE_IPMI_HPM_2 = 260,
237
    /// Per Joshua Wright <jwright@hasborg.com>, formats for Z-Wave RF profiles R1 and R2 captures
238
    LINKTYPE_ZWAVE_R1_R2 = 261,
239
    /// Per Joshua Wright <jwright@hasborg.com>, formats for Z-Wave RF profile R3 captures
240
    LINKTYPE_ZWAVE_R3 = 262,
241
    /// Formats for WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol common packet
242
    /// structure captures
243
    LINKTYPE_WATTSTOPPER_DLM = 263,
244
    /// Messages between ISO 14443 contactless smartcards (Proximity Integrated Circuit Card, PICC) and card readers
245
    /// (Proximity Coupling Device, PCD), with the message format specified by the PCAP format for ISO14443
246
    /// specification
247
    LINKTYPE_ISO_14443 = 264,
248
    /// Linux "cooked" capture encapsulation v2
249
    LINKTYPE_LINUX_SLL2 = 276,
250
    /// Set if interface ID for a packet of a pcapng file is too high
251
    LINKTYPE_INVALID = 0xFFFF
252
  };
253
254
  /// Convert a link layer type to its string representation.
255
  /// @param[in] linkLayer The link layer type to convert.
256
  /// @return The string representation of the link layer type.
257
  constexpr const char* linkLayerToString(LinkLayerType linkLayer)
258
0
  {
259
0
    switch (linkLayer)
260
0
    {
261
0
    case LINKTYPE_NULL:
262
0
      return "NULL";
263
0
    case LINKTYPE_ETHERNET:
264
0
      return "Ethernet";
265
0
    case LINKTYPE_AX25:
266
0
      return "AX.25";
267
0
    case LINKTYPE_IEEE802_5:
268
0
      return "IEEE 802.5";
269
0
    case LINKTYPE_ARCNET_BSD:
270
0
      return "ARCNET BSD";
271
0
    case LINKTYPE_SLIP:
272
0
      return "SLIP";
273
0
    case LINKTYPE_PPP:
274
0
      return "PPP";
275
0
    case LINKTYPE_FDDI:
276
0
      return "FDDI";
277
0
    case LINKTYPE_DLT_RAW1:
278
0
      return "DLT_RAW1";
279
0
    case LINKTYPE_DLT_RAW2:
280
0
      return "DLT_RAW2";
281
0
    case LINKTYPE_PPP_HDLC:
282
0
      return "PPP HDLC";
283
0
    case LINKTYPE_PPP_ETHER:
284
0
      return "PPPoE";
285
0
    case LINKTYPE_ATM_RFC1483:
286
0
      return "ATM RFC1483";
287
0
    case LINKTYPE_RAW:
288
0
      return "Raw";
289
0
    case LINKTYPE_C_HDLC:
290
0
      return "Cisco HDLC";
291
0
    case LINKTYPE_IEEE802_11:
292
0
      return "IEEE 802.11";
293
0
    case LINKTYPE_FRELAY:
294
0
      return "Frame Relay";
295
0
    case LINKTYPE_LOOP:
296
0
      return "OpenBSD Loopback";
297
0
    case LINKTYPE_LINUX_SLL:
298
0
      return "Linux SLL";
299
0
    case LINKTYPE_LTALK:
300
0
      return "LocalTalk";
301
0
    case LINKTYPE_PFLOG:
302
0
      return "PFLOG";
303
0
    case LINKTYPE_IEEE802_11_PRISM:
304
0
      return "IEEE 802.11 Prism";
305
0
    case LINKTYPE_IP_OVER_FC:
306
0
      return "IP over Fibre Channel";
307
0
    case LINKTYPE_SUNATM:
308
0
      return "SunATM";
309
0
    case LINKTYPE_IEEE802_11_RADIOTAP:
310
0
      return "IEEE 802.11 Radiotap";
311
0
    case LINKTYPE_ARCNET_LINUX:
312
0
      return "ARCNET Linux";
313
0
    case LINKTYPE_APPLE_IP_OVER_IEEE1394:
314
0
      return "Apple IP over IEEE 1394";
315
0
    case LINKTYPE_MTP2_WITH_PHDR:
316
0
      return "MTP2 with PHDR";
317
0
    case LINKTYPE_MTP2:
318
0
      return "MTP2";
319
0
    case LINKTYPE_MTP3:
320
0
      return "MTP3";
321
0
    case LINKTYPE_SCCP:
322
0
      return "SCCP";
323
0
    case LINKTYPE_DOCSIS:
324
0
      return "DOCSIS";
325
0
    case LINKTYPE_LINUX_IRDA:
326
0
      return "Linux IrDA";
327
0
328
0
    case LINKTYPE_USER0:
329
0
      return "USER0";
330
0
    case LINKTYPE_USER1:
331
0
      return "USER1";
332
0
    case LINKTYPE_USER2:
333
0
      return "USER2";
334
0
    case LINKTYPE_USER3:
335
0
      return "USER3";
336
0
    case LINKTYPE_USER4:
337
0
      return "USER4";
338
0
    case LINKTYPE_USER5:
339
0
      return "USER5";
340
0
    case LINKTYPE_USER6:
341
0
      return "USER6";
342
0
    case LINKTYPE_USER7:
343
0
      return "USER7";
344
0
    case LINKTYPE_USER8:
345
0
      return "USER8";
346
0
    case LINKTYPE_USER9:
347
0
      return "USER9";
348
0
    case LINKTYPE_USER10:
349
0
      return "USER10";
350
0
    case LINKTYPE_USER11:
351
0
      return "USER11";
352
0
    case LINKTYPE_USER12:
353
0
      return "USER12";
354
0
    case LINKTYPE_USER13:
355
0
      return "USER13";
356
0
    case LINKTYPE_USER14:
357
0
      return "USER14";
358
0
    case LINKTYPE_USER15:
359
0
      return "USER15";
360
0
361
0
    case LINKTYPE_IEEE802_11_AVS:
362
0
      return "IEEE 802.11 AVS";
363
0
    case LINKTYPE_BACNET_MS_TP:
364
0
      return "BACnet MS/TP";
365
0
    case LINKTYPE_PPP_PPPD:
366
0
      return "PPP PPPD";
367
0
    case LINKTYPE_GPRS_LLC:
368
0
      return "GPRS LLC";
369
0
    case LINKTYPE_GPF_T:
370
0
      return "GPF-T";
371
0
    case LINKTYPE_GPF_F:
372
0
      return "GPF-F";
373
0
    case LINKTYPE_LINUX_LAPD:
374
0
      return "Linux LAPD";
375
0
    case LINKTYPE_BLUETOOTH_HCI_H4:
376
0
      return "Bluetooth HCI H4";
377
0
    case LINKTYPE_USB_LINUX:
378
0
      return "USB Linux";
379
0
    case LINKTYPE_PPI:
380
0
      return "PPI";
381
0
    case LINKTYPE_IEEE802_15_4:
382
0
      return "IEEE 802.15.4";
383
0
    case LINKTYPE_SITA:
384
0
      return "SITA";
385
0
    case LINKTYPE_ERF:
386
0
      return "ERF";
387
0
    case LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR:
388
0
      return "Bluetooth HCI H4 with PHDR";
389
0
    case LINKTYPE_AX25_KISS:
390
0
      return "AX.25 KISS";
391
0
    case LINKTYPE_LAPD:
392
0
      return "LAPD";
393
0
    case LINKTYPE_PPP_WITH_DIR:
394
0
      return "PPP with Direction";
395
0
    case LINKTYPE_C_HDLC_WITH_DIR:
396
0
      return "Cisco HDLC with Direction";
397
0
    case LINKTYPE_FRELAY_WITH_DIR:
398
0
      return "Frame Relay with Direction";
399
0
    case LINKTYPE_IPMB_LINUX:
400
0
      return "IPMB Linux";
401
0
    case LINKTYPE_IEEE802_15_4_NONASK_PHY:
402
0
      return "IEEE 802.15.4 NONASK PHY";
403
0
    case LINKTYPE_USB_LINUX_MMAPPED:
404
0
      return "USB Linux MMAPPED";
405
0
    case LINKTYPE_FC_2:
406
0
      return "Fibre Channel FC-2";
407
0
    case LINKTYPE_FC_2_WITH_FRAME_DELIMS:
408
0
      return "Fibre Channel FC-2 with Frame Delimiters";
409
0
    case LINKTYPE_IPNET:
410
0
      return "Solaris IPNET";
411
0
    case LINKTYPE_CAN_SOCKETCAN:
412
0
      return "CAN SocketCAN";
413
0
    case LINKTYPE_IPV4:
414
0
      return "IPv4";
415
0
    case LINKTYPE_IPV6:
416
0
      return "IPv6";
417
0
    case LINKTYPE_IEEE802_15_4_NOFCS:
418
0
      return "IEEE 802.15.4 without FCS";
419
0
    case LINKTYPE_DBUS:
420
0
      return "D-Bus";
421
0
    case LINKTYPE_DVB_CI:
422
0
      return "DVB-CI";
423
0
    case LINKTYPE_MUX27010:
424
0
      return "MUX27010";
425
0
    case LINKTYPE_STANAG_5066_D_PDU:
426
0
      return "STANAG 5066 D-PDU";
427
0
    case LINKTYPE_NFLOG:
428
0
      return "NFLOG";
429
0
    case LINKTYPE_NETANALYZER:
430
0
      return "netANALYZER";
431
0
    case LINKTYPE_NETANALYZER_TRANSPARENT:
432
0
      return "netANALYZER Transparent";
433
0
    case LINKTYPE_IPOIB:
434
0
      return "IP over InfiniBand";
435
0
    case LINKTYPE_MPEG_2_TS:
436
0
      return "MPEG-2 Transport Stream";
437
0
    case LINKTYPE_NG40:
438
0
      return "NG40";
439
0
    case LINKTYPE_NFC_LLCP:
440
0
      return "NFC LLCP";
441
0
    case LINKTYPE_INFINIBAND:
442
0
      return "InfiniBand";
443
0
    case LINKTYPE_SCTP:
444
0
      return "SCTP";
445
0
    case LINKTYPE_USBPCAP:
446
0
      return "USBPcap";
447
0
    case LINKTYPE_RTAC_SERIAL:
448
0
      return "RTAC Serial";
449
0
    case LINKTYPE_BLUETOOTH_LE_LL:
450
0
      return "Bluetooth LE LL";
451
0
    case LINKTYPE_NETLINK:
452
0
      return "Netlink";
453
0
    case LINKTYPE_BLUETOOTH_LINUX_MONITOR:
454
0
      return "Bluetooth Linux Monitor";
455
0
    case LINKTYPE_BLUETOOTH_BREDR_BB:
456
0
      return "Bluetooth BR/EDR Baseband";
457
0
    case LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR:
458
0
      return "Bluetooth LE LL with PHDR";
459
0
    case LINKTYPE_PROFIBUS_DL:
460
0
      return "PROFIBUS DL";
461
0
    case LINKTYPE_PKTAP:
462
0
      return "PKTAP";
463
0
    case LINKTYPE_EPON:
464
0
      return "EPON";
465
0
    case LINKTYPE_IPMI_HPM_2:
466
0
      return "IPMI HPM.2";
467
0
    case LINKTYPE_ZWAVE_R1_R2:
468
0
      return "Z-Wave R1/R2";
469
0
    case LINKTYPE_ZWAVE_R3:
470
0
      return "Z-Wave R3";
471
0
    case LINKTYPE_WATTSTOPPER_DLM:
472
0
      return "WattStopper DLM";
473
0
    case LINKTYPE_ISO_14443:
474
0
      return "ISO 14443";
475
0
    case LINKTYPE_LINUX_SLL2:
476
0
      return "Linux SLL2";
477
0
    case LINKTYPE_INVALID:
478
0
      return "Invalid";
479
0
480
0
    default:
481
0
      throw std::invalid_argument("Unknown link type");
482
0
    }
483
0
  }
484
485
  /// Max packet size supported
486
0
#define PCPP_MAX_PACKET_SIZE 65536
487
488
  class RawPacket;
489
490
  namespace internal
491
  {
492
    /// @brief Type of RawPacket implementation
493
    ///
494
    /// This is mainly used internally to distinguish between different implementations without using RTTI.
495
    ///
496
    /// Only the standard RawPacket implementation is defined in Packet++ library.
497
    /// Other device specific implementations are defined in their respective parts of Pcap++.
498
    enum class RawPacketImplType : uint8_t
499
    {
500
      /// @brief Unknown type
501
      Unknown = 0,
502
      /// @brief Standard RawPacket
503
      Standard = 1,
504
      /// @brief DPDK MBuf based RawPacket
505
      DpdkMBuf = 2,
506
      /// @brief WinDivert based RawPacket
507
      WinDivert = 3
508
    };
509
510
    /// @brief Get the concrete implementation type of a RawPacket instance
511
    /// @param rawPacket The RawPacket instance
512
    /// @return A value of RawPacketImplType enum representing the concrete implementation type of the given
513
    /// RawPacket instance.
514
    RawPacketImplType getRawPacketImplementationType(RawPacket const& rawPacket);
515
  }  // namespace internal
516
517
  /// @class RawPacket
518
  /// This class holds the packet as raw (not parsed) data. The data is held as byte array. In addition to the data
519
  /// itself every instance also holds a timestamp representing the time the packet was received by the NIC. RawPacket
520
  /// instance isn't read only. The user can change the packet data, add or remove data, etc.
521
  class RawPacket
522
  {
523
    friend internal::RawPacketImplType internal::getRawPacketImplementationType(RawPacket const& rawPacket);
524
525
  protected:
526
    uint8_t* m_RawData = nullptr;
527
    int m_RawDataLen = 0;
528
    int m_FrameLength = 0;
529
    timespec m_TimeStamp{};  // Zero initialized
530
    bool m_OwnsRawData = false;
531
    bool m_RawPacketSet = false;
532
    LinkLayerType m_LinkLayerType = LinkLayerType::LINKTYPE_ETHERNET;
533
534
    void copyDataFrom(const RawPacket& other, bool allocateData = true);
535
536
  public:
537
    /// A default constructor that initializes class'es attributes to default value:
538
    /// - data pointer is set to nullptr
539
    /// - data length is set to 0
540
    /// - frame length is set to 0
541
    /// - takeOwnership is set to 'false'
542
    /// - timestamp is set to 0
543
    /// - layer type is set to Ethernet
544
693
    RawPacket() = default;
545
546
    /// A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually
547
    /// used when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.).
548
    /// The capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has
549
    /// arrived to the device
550
    /// @param[in] pRawData A pointer to the raw data
551
    /// @param[in] rawDataLen The raw data length in bytes
552
    /// @param[in] timestamp The timestamp packet was received by the NIC (in usec precision)
553
    /// @param[in] takeOwnership If 'true' the RawPacket will take ownership of the pRawData pointer and will
554
    /// free it when the RawPacket instance is destroyed or the buffer is replaced.
555
    /// @param[in] layerType The link layer type of this raw packet. The default is Ethernet
556
    RawPacket(const uint8_t* pRawData, int rawDataLen, timeval timestamp, bool takeOwnership,
557
              LinkLayerType layerType = LINKTYPE_ETHERNET);
558
559
    /// A constructor that receives a pointer to the raw data (allocated elsewhere). This constructor is usually
560
    /// used when packet is captured using a packet capturing engine (like libPcap. WinPcap, Npcap, PF_RING, etc.).
561
    /// The capturing engine allocates the raw data memory and give the user a pointer to it + a timestamp it has
562
    /// arrived to the device
563
    /// @param[in] pRawData A pointer to the raw data
564
    /// @param[in] rawDataLen The raw data length in bytes
565
    /// @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision)
566
    /// @param[in] takeOwnership If 'true' the RawPacket will take ownership of the pRawData pointer and will
567
    /// free it when the RawPacket instance is destroyed or the buffer is replaced.
568
    /// @param[in] layerType The link layer type of this raw packet. The default is Ethernet
569
    RawPacket(const uint8_t* pRawData, int rawDataLen, timespec timestamp, bool takeOwnership,
570
              LinkLayerType layerType = LINKTYPE_ETHERNET);
571
572
    /// A destructor for this class. Frees the raw data if takeOwnership was set to 'true'
573
    virtual ~RawPacket();
574
575
    /// A copy constructor that copies all data from another instance. Notice all raw data is copied (using memcpy),
576
    /// so when the original or the other instance are freed, the other won't be affected
577
    /// @param[in] other The instance to copy from
578
    RawPacket(const RawPacket& other);
579
580
    /// Assignment operator overload for this class. When using this operator on an already initialized RawPacket
581
    /// instance, the original raw data is freed first if takeOwnership was set to 'true'.
582
    /// Then the other instance is copied to this instance, the same way the copy constructor works
583
    /// @param[in] other The instance to copy from
584
    RawPacket& operator=(const RawPacket& other);
585
586
    /// @brief Clones the current packet. Caller is responsible for deallocation of the memory.
587
    /// @return A pointer to the new RawPacket object which is a clone of this object
588
    virtual RawPacket* clone() const;
589
590
    /// @return RawPacket object type. Each derived class should return a different value
591
    /// @deprecated Deprecated due to unclear semantics and type safety.
592
    /// The functionality has been moved to the unstable internal API in as
593
    /// internal::getRawPacketImplementationType(RawPacket const& rawPacket).
594
    PCPP_DEPRECATED("Deprecated due to unclear semantics.")
595
    virtual uint8_t getObjectType() const
596
0
    {
597
0
      return 0;
598
0
    }
599
600
    /// Set a raw data. If data was already set and takeOwnership was set to 'true' the old data will be
601
    /// freed first
602
    /// @param[in] pRawData A pointer to the new raw data
603
    /// @param[in] rawDataLen The new raw data length in bytes
604
    /// @param[in] timestamp The timestamp packet was received by the NIC (in usec precision)
605
    /// @param[in] layerType The link layer type for this raw data
606
    /// @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the
607
    /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or
608
    /// set to -1 it is assumed both lengths are equal
609
    /// @return True if raw data was set successfully, false otherwise
610
    /// @deprecated This method does not update ownership of the pRawData pointer, inheriting the previous buffer's
611
    /// ownership. Use the overload that takes bool takeOwnership parameter for explicit control.
612
    /// @remarks Derived classes may not support using the raw data buffer directly.
613
    /// Users should not rely on the RawPacket always writing to the provided pointer location,
614
    /// and instead get the raw data pointer using getRawData().
615
    PCPP_DEPRECATED("Use the overload that takes bool takeOwnership parameter for explicit control.")
616
    bool setRawData(const uint8_t* pRawData, int rawDataLen, timeval timestamp,
617
                    LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1);
618
619
    /// @brief Assign a buffer to use as raw data.
620
    ///
621
    /// If the RawPacket already had raw data, it will be disposed of accordingly.
622
    ///
623
    /// @param pRawData A pointer to the new raw data buffer.
624
    /// @param rawDataLen The length of the new raw data buffer in bytes.
625
    /// @param takeOwnership If true, the RawPacket will take ownership of the buffer and will be responsible for
626
    /// freeing it.
627
    /// @param timestamp The timestamp packet was received by the NIC (in usec precision).
628
    /// @param layerType The link layer type for this raw data.
629
    /// @param frameLength When reading from pcap files, sometimes the captured length is different from the
630
    /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or
631
    /// set to -1 it is assumed both lengths are equal
632
    /// @return True if raw data was set successfully, false otherwise.
633
    /// @remarks Derived classes may not support using the raw data buffer directly.
634
    /// Users should not rely on the RawPacket always writing to the provided pointer location,
635
    /// and instead get the raw data pointer using getRawData().
636
    bool setRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timeval timestamp,
637
                    LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1);
638
639
    /// Set a raw data. If data was already set and takeOwnership was set to 'true' the old data will be
640
    /// freed first
641
    /// @param[in] pRawData A pointer to the new raw data
642
    /// @param[in] rawDataLen The new raw data length in bytes
643
    /// @param[in] timestamp The timestamp packet was received by the NIC (in nsec precision)
644
    /// @param[in] layerType The link layer type for this raw data
645
    /// @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the
646
    /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or
647
    /// set to -1 it is assumed both lengths are equal
648
    /// @return True if raw data was set successfully, false otherwise
649
    /// @deprecated This method does not update ownership of the pRawData pointer, inheriting the previous buffer's
650
    /// ownership. Use the overload that takes bool takeOwnership parameter for explicit control.
651
    /// @remarks Derived classes may not support using the raw data buffer directly.
652
    /// Users should not rely on the RawPacket always writing to the provided pointer location,
653
    /// and instead get the raw data pointer using getRawData().
654
    PCPP_DEPRECATED("Use the overload that takes bool takeOwnership parameter for explicit control.")
655
    bool setRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp,
656
                    LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1);
657
658
    /// @brief Assign a buffer to use as raw data.
659
    ///
660
    /// If the RawPacket already had raw data, it will be disposed of accordingly.
661
    ///
662
    /// @param pRawData A pointer to the new raw data buffer.
663
    /// @param rawDataLen The length of the new raw data buffer in bytes.
664
    /// @param takeOwnership If true, the RawPacket will take ownership of the buffer and will be responsible for
665
    /// freeing it.
666
    /// @param timestamp The timestamp packet was received by the NIC (in nsec precision).
667
    /// @param layerType The link layer type for this raw data.
668
    /// @param frameLength When reading from pcap files, sometimes the captured length is different from the
669
    /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or
670
    /// set to -1 it is assumed both lengths are equal
671
    /// @return True if raw data was set successfully, false otherwise.
672
    /// @remarks Derived classes may not support using the raw data buffer directly.
673
    /// Users should not rely on the RawPacket always writing to the provided pointer location,
674
    /// and instead get the raw data pointer using getRawData().
675
    bool setRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timespec timestamp,
676
                    LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1);
677
678
    /// Initialize a raw packet with data. The main difference between this method and setRawData() is that
679
    /// setRawData() is meant for replacing the data in an existing raw packet, whereas this method is meant to be
680
    /// used right after constructing a raw packet using the default c'tor, before setting any data
681
    /// @param pRawData A pointer to the new raw data
682
    /// @param rawDataLen The new raw data length in bytes
683
    /// @param timestamp The timestamp packet was received by the NIC (in nsec precision)
684
    /// @param layerType The link layer type for this raw data
685
    /// @return True if raw data was set successfully, false otherwise
686
    /// @deprecated Prefer using setRawData() with takeOwnership `false`.
687
    PCPP_DEPRECATED("Prefer using setRawData() with takeOwnership `false`.")
688
    bool initWithRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp,
689
                         LinkLayerType layerType = LINKTYPE_ETHERNET);
690
691
    /// Get raw data pointer
692
    /// @return A read-only pointer to the raw data
693
    const uint8_t* getRawData() const
694
9.24k
    {
695
9.24k
      return m_RawData;
696
9.24k
    }
697
698
    /// Get the link layer type
699
    /// @return the type of the link layer
700
    LinkLayerType getLinkLayerType() const
701
9.24k
    {
702
9.24k
      return m_LinkLayerType;
703
9.24k
    }
704
705
    /// This static method validates whether a link type integer value is valid
706
    /// @param[in] linkTypeValue Link type integer value
707
    /// @return True if the link type value is valid and can be casted into LinkLayerType enum, false otherwise
708
    static bool isLinkTypeValid(int linkTypeValue);
709
710
    /// Get raw data length in bytes
711
    /// @return Raw data length in bytes
712
    int getRawDataLen() const
713
9.24k
    {
714
9.24k
      return m_RawDataLen;
715
9.24k
    }
716
717
    /// Get frame length in bytes
718
    /// @return frame length in bytes
719
    int getFrameLength() const
720
4.62k
    {
721
4.62k
      return m_FrameLength;
722
4.62k
    }
723
    /// Get raw data timestamp
724
    /// @return Raw data timestamp
725
    timespec getPacketTimeStamp() const
726
9.24k
    {
727
9.24k
      return m_TimeStamp;
728
9.24k
    }
729
730
    /// Set raw packet timestamp with usec precision
731
    /// @param[in] timestamp The timestamp to set (with usec precision)
732
    /// @return True if timestamp was set successfully, false otherwise
733
    virtual bool setPacketTimeStamp(timeval timestamp);
734
735
    /// Set raw packet timestamp with nsec precision
736
    /// @param[in] timestamp The timestamp to set (with nsec precision)
737
    /// @return True if timestamp was set successfully, false otherwise
738
    virtual bool setPacketTimeStamp(timespec timestamp);
739
740
    /// Get an indication whether raw data was already set for this instance.
741
    /// @return True if raw data was set for this instance. Raw data can be set using the non-default constructor,
742
    /// using setRawData(), using the copy constructor or using the assignment operator. Returns false otherwise,
743
    /// for example: if the instance was created using the default constructor or clear() was called
744
    bool isPacketSet() const
745
0
    {
746
0
      return m_RawPacketSet;
747
0
    }
748
749
    /// Clears all members of this instance, meaning setting raw data to nullptr, raw data length to 0, etc.
750
    /// Frees the raw data if takeOwnership was set to 'true'
751
    /// @todo set timestamp to a default value as well
752
    virtual void clear();
753
754
    /// Append data to the end of current data. This method works without allocating more memory, it just uses
755
    /// memcpy() to copy dataToAppend at the end of the current data. This means that the method assumes this memory
756
    /// was already allocated by the user. If it isn't the case then this method will cause memory corruption
757
    /// @param[in] dataToAppend A pointer to the data to append to current raw data
758
    /// @param[in] dataToAppendLen Length in bytes of dataToAppend
759
    virtual void appendData(const uint8_t* dataToAppend, size_t dataToAppendLen);
760
761
    /// Insert new data at some index of the current data and shift the remaining old data to the end. This method
762
    /// works without allocating more memory, it just copies dataToAppend at the relevant index and shifts the
763
    /// remaining data to the end. This means that the method assumes this memory was already allocated by the user.
764
    /// If it isn't the case then this method will cause memory corruption
765
    /// @param[in] atIndex The index to insert the new data to
766
    /// @param[in] dataToInsert A pointer to the new data to insert
767
    /// @param[in] dataToInsertLen Length in bytes of dataToInsert
768
    virtual void insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen);
769
770
    /// Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be
771
    /// shifted back
772
    /// @param[in] atIndex The index to start removing bytes from
773
    /// @param[in] numOfBytesToRemove Number of bytes to remove
774
    /// @return True if all bytes were removed successfully, or false if atIndex+numOfBytesToRemove is out-of-bounds
775
    /// of the raw data buffer
776
    virtual bool removeData(int atIndex, size_t numOfBytesToRemove);
777
778
    /// Re-allocate raw packet buffer meaning add size to it without losing the current packet data. This method
779
    /// allocates the required buffer size as instructed by the use and then copies the raw data from the current
780
    /// allocated buffer to the new one. This method can become useful if the user wants to insert or append data to
781
    /// the raw data, and the previous allocated buffer is too small, so the user wants to allocate a larger buffer
782
    /// and get RawPacket instance to point to it
783
    /// @param[in] newBufferLength The new buffer length as required by the user. The method is responsible to
784
    /// allocate the memory
785
    /// @return True if data was reallocated successfully, false otherwise
786
    virtual bool reallocateData(size_t newBufferLength);
787
788
  protected:
789
    /// @brief Get the type of RawPacket implementation.
790
    virtual internal::RawPacketImplType getImplType() const
791
0
    {
792
0
      return internal::RawPacketImplType::Standard;
793
0
    }
794
795
    // Updates the raw data buffer and related members. Used by setRawData() methods.
796
    virtual bool doSetRawData(const uint8_t* pRawData, int rawDataLen, bool takeOwnership, timespec timestamp,
797
                              LinkLayerType layerType, int frameLength);
798
  };
799
800
  namespace internal
801
  {
802
    inline RawPacketImplType getRawPacketImplementationType(RawPacket const& rawPacket)
803
0
    {
804
0
      return rawPacket.getImplType();
805
0
    }
806
  }  // namespace internal
807
}  // namespace pcpp