Coverage Report

Created: 2025-07-11 07:47

/src/PcapPlusPlus/Packet++/header/GtpLayer.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include "Layer.h"
4
#include "TLVData.h"
5
#include <vector>
6
#include <bitset>
7
8
/// @file
9
10
/// @namespace pcpp
11
/// @brief The main namespace for the PcapPlusPlus lib
12
namespace pcpp
13
{
14
15
#pragma pack(push, 1)
16
  /// @struct gtpv1_header
17
  /// GTP v1 common message header
18
  struct gtpv1_header
19
  {
20
#if (BYTE_ORDER == LITTLE_ENDIAN)
21
    /// A 1-bit value that states whether there is a N-PDU number optional field
22
    uint8_t npduNumberFlag : 1,
23
        /// A 1-bit value that states whether there is a Sequence Number optional field
24
        sequenceNumberFlag : 1,
25
        /// A 1-bit value that states whether there is an extension header optional field
26
        extensionHeaderFlag : 1,
27
        /// Reserved bit
28
        reserved : 1,
29
        /// A 1-bit value that differentiates GTP (value 1) from GTP' (value 0)
30
        protocolType : 1,
31
        /// GTP version
32
        version : 3;
33
#else
34
    /// GTP version
35
    uint8_t version : 3,
36
        /// A 1-bit value that differentiates GTP (value 1) from GTP' (value 0)
37
        protocolType : 1,
38
        /// Reserved bit
39
        reserved : 1,
40
        /// A 1-bit value that states whether there is an extension header optional field
41
        extensionHeaderFlag : 1,
42
        /// A 1-bit value that states whether there is a Sequence Number optional field
43
        sequenceNumberFlag : 1,
44
        /// A 1-bit value that states whether there is a N-PDU number optional field
45
        npduNumberFlag : 1;
46
#endif
47
    /// An 8-bit field that indicates the type of GTP message
48
    uint8_t messageType;
49
50
    /// A 16-bit field that indicates the length of the payload in bytes (rest of the packet following the mandatory
51
    /// 8-byte GTP header). Includes the optional fields
52
    uint16_t messageLength;
53
54
    /// Tunnel endpoint identifier - A 32-bit(4-octet) field used to multiplex different connections in the same GTP
55
    /// tunnel
56
    uint32_t teid;
57
  };
58
#pragma pack(pop)
59
  static_assert(sizeof(gtpv1_header) == 8, "gtpv1_header size is not 8 bytes");
60
61
  /// An enum representing the possible GTP v1 message types.
62
  /// All of the message types except for #GtpV1_GPDU are considered GTP-C messages. #GtpV1_GPDU is considered a GTP-U
63
  /// message
64
  enum GtpV1MessageType
65
  {
66
    /// GTPv1 Message Type Unknown
67
    GtpV1_MessageTypeUnknown = 0,
68
    /// Echo Request
69
    GtpV1_EchoRequest = 1,
70
    /// Echo Response
71
    GtpV1_EchoResponse = 2,
72
    /// Version Not Supported
73
    GtpV1_VersionNotSupported = 3,
74
    /// Node Alive Request
75
    GtpV1_NodeAliveRequest = 4,
76
    /// Node Alive Response
77
    GtpV1_NodeAliveResponse = 5,
78
    /// Redirection Request
79
    GtpV1_RedirectionRequest = 6,
80
    /// Create PDP Context Request
81
    GtpV1_CreatePDPContextRequest = 7,
82
    /// Create PDP Context Response
83
    GtpV1_CreatePDPContextResponse = 16,
84
    /// Update PDP Context Request
85
    GtpV1_UpdatePDPContextRequest = 17,
86
    /// Update PDP Context Response
87
    GtpV1_UpdatePDPContextResponse = 18,
88
    /// Delete PDP Context Request
89
    GtpV1_DeletePDPContextRequest = 19,
90
    /// Delete PDP Context Response
91
    GtpV1_DeletePDPContextResponse = 20,
92
    /// Initiate PDP Context Activation Request
93
    GtpV1_InitiatePDPContextActivationRequest = 22,
94
    /// Initiate PDP Context Activation Response
95
    GtpV1_InitiatePDPContextActivationResponse = 23,
96
    /// Error Indication
97
    GtpV1_ErrorIndication = 26,
98
    /// PDU Notification Request
99
    GtpV1_PDUNotificationRequest = 27,
100
    /// PDU Notification Response
101
    GtpV1_PDUNotificationResponse = 28,
102
    /// PDU Notification Reject Request
103
    GtpV1_PDUNotificationRejectRequest = 29,
104
    /// PDU Notification Reject Response
105
    GtpV1_PDUNotificationRejectResponse = 30,
106
    /// Supported Extensions Header Notification
107
    GtpV1_SupportedExtensionsHeaderNotification = 31,
108
    /// Send Routing for GPRS Request
109
    GtpV1_SendRoutingforGPRSRequest = 32,
110
    /// Send Routing for GPRS Response
111
    GtpV1_SendRoutingforGPRSResponse = 33,
112
    /// Failure Report Request
113
    GtpV1_FailureReportRequest = 34,
114
    /// Failure Report Response
115
    GtpV1_FailureReportResponse = 35,
116
    /// Note MS Present Request
117
    GtpV1_NoteMSPresentRequest = 36,
118
    /// Note MS Present Response
119
    GtpV1_NoteMSPresentResponse = 37,
120
    /// Identification Request
121
    GtpV1_IdentificationRequest = 38,
122
    /// Identification Response
123
    GtpV1_IdentificationResponse = 39,
124
    /// SGSN Context Request
125
    GtpV1_SGSNContextRequest = 50,
126
    /// SGSN Context Response
127
    GtpV1_SGSNContextResponse = 51,
128
    /// SGSN Context Acknowledge
129
    GtpV1_SGSNContextAcknowledge = 52,
130
    /// Forward Relocation Request
131
    GtpV1_ForwardRelocationRequest = 53,
132
    /// Forward Relocation Response
133
    GtpV1_ForwardRelocationResponse = 54,
134
    /// Forward Relocation Complete
135
    GtpV1_ForwardRelocationComplete = 55,
136
    /// Relocation Cancel Request
137
    GtpV1_RelocationCancelRequest = 56,
138
    /// Relocation Cancel Response
139
    GtpV1_RelocationCancelResponse = 57,
140
    /// Forward SRNS Context
141
    GtpV1_ForwardSRNSContext = 58,
142
    /// Forward Relocation Complete Acknowledge
143
    GtpV1_ForwardRelocationCompleteAcknowledge = 59,
144
    /// Forward SRNS Context Acknowledge
145
    GtpV1_ForwardSRNSContextAcknowledge = 60,
146
    /// UE Registration Request
147
    GtpV1_UERegistrationRequest = 61,
148
    /// UE Registration Response
149
    GtpV1_UERegistrationResponse = 62,
150
    /// RAN Information Relay
151
    GtpV1_RANInformationRelay = 70,
152
    /// MBMS Notification Request
153
    GtpV1_MBMSNotificationRequest = 96,
154
    /// MBMS Notification Response
155
    GtpV1_MBMSNotificationResponse = 97,
156
    /// MBMS Notification Reject Request
157
    GtpV1_MBMSNotificationRejectRequest = 98,
158
    /// MBMS Notification Reject Response
159
    GtpV1_MBMSNotificationRejectResponse = 99,
160
    /// Create MBMS Notification Request
161
    GtpV1_CreateMBMSNotificationRequest = 100,
162
    /// Create MBMS Notification Response
163
    GtpV1_CreateMBMSNotificationResponse = 101,
164
    /// Update MBMS Notification Request
165
    GtpV1_UpdateMBMSNotificationRequest = 102,
166
    /// Update MBMS Notification Response
167
    GtpV1_UpdateMBMSNotificationResponse = 103,
168
    /// Delete MBMS Notification Request
169
    GtpV1_DeleteMBMSNotificationRequest = 104,
170
    /// Delete MBMS Notification Response
171
    GtpV1_DeleteMBMSNotificationResponse = 105,
172
    /// MBMS Registration Request
173
    GtpV1_MBMSRegistrationRequest = 112,
174
    /// MBMS Registration Response
175
    GtpV1_MBMSRegistrationResponse = 113,
176
    /// MBMS De-Registration Request
177
    GtpV1_MBMSDeRegistrationRequest = 114,
178
    /// MBMS De-Registration Response
179
    GtpV1_MBMSDeRegistrationResponse = 115,
180
    /// MBMS Session Start Request
181
    GtpV1_MBMSSessionStartRequest = 116,
182
    /// MBMS Session Start Response
183
    GtpV1_MBMSSessionStartResponse = 117,
184
    /// MBMS Session Stop Request
185
    GtpV1_MBMSSessionStopRequest = 118,
186
    /// MBMS Session Stop Response
187
    GtpV1_MBMSSessionStopResponse = 119,
188
    /// MBMS Session Update Request
189
    GtpV1_MBMSSessionUpdateRequest = 120,
190
    /// MBMS Session Update Response
191
    GtpV1_MBMSSessionUpdateResponse = 121,
192
    /// MS Info Change Request
193
    GtpV1_MSInfoChangeRequest = 128,
194
    /// MS Info Change Response
195
    GtpV1_MSInfoChangeResponse = 129,
196
    /// Data Record Transfer Request
197
    GtpV1_DataRecordTransferRequest = 240,
198
    /// Data Record Transfer Response
199
    GtpV1_DataRecordTransferResponse = 241,
200
    /// End Marker
201
    GtpV1_EndMarker = 254,
202
    /// G-PDU
203
    GtpV1_GPDU = 255
204
  };
205
206
  /// @class GtpV1Layer
207
  /// A class representing the [GTP v1](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol) protocol.
208
  class GtpV1Layer : public Layer
209
  {
210
  private:
211
    struct gtpv1_header_extra
212
    {
213
      uint16_t sequenceNumber;
214
      uint8_t npduNumber;
215
      uint8_t nextExtensionHeader;
216
    };
217
218
    gtpv1_header_extra* getHeaderExtra() const;
219
220
    void init(GtpV1MessageType messageType, uint32_t teid, bool setSeqNum, uint16_t seqNum, bool setNpduNum,
221
              uint8_t npduNum);
222
223
  public:
224
    /// @class GtpExtension
225
    /// A class that represents [GTP header extensions](https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol)
226
    class GtpExtension
227
    {
228
      friend class GtpV1Layer;
229
230
    private:
231
      uint8_t* m_Data;
232
      size_t m_DataLen;
233
      uint8_t m_ExtType;
234
235
      GtpExtension(uint8_t* data, size_t dataLen, uint8_t type);
236
237
      void setNextHeaderType(uint8_t nextHeaderType);
238
239
      static GtpExtension createGtpExtension(uint8_t* data, size_t dataLen, uint8_t extType, uint16_t content);
240
241
    public:
242
      /// An empty c'tor that creates an empty object, meaning one that isNull() returns "true")
243
      GtpExtension();
244
245
      /// A copy c'tor for this class
246
      /// @param[in] other The GTP extension to copy from
247
      GtpExtension(const GtpExtension& other);
248
249
      /// An assignment operator for this class
250
      /// @param[in] other The extension to assign from
251
      /// @return A reference to the assignee
252
      GtpExtension& operator=(const GtpExtension& other);
253
254
      /// @return Instances of this class may be initialized as empty, meaning they don't contain any data. In
255
      /// these cases this method returns true
256
      bool isNull() const;
257
258
      /// @return The extension type. If the object is empty a value of zero is returned
259
      uint8_t getExtensionType() const;
260
261
      /// @return The total length of the extension including the length and next extension type fields.
262
      /// If the object is empty a value of zero is returned
263
      size_t getTotalLength() const;
264
265
      /// @return The length of the extension's content, excluding the extension length and next extension type
266
      /// fields. If the object is empty a value of zero is returned
267
      size_t getContentLength() const;
268
269
      /// @return A byte array that includes the extension's content. The length of this array can be determined
270
      /// by getContentLength(). If the object is empty a null value is returned
271
      uint8_t* getContent() const;
272
273
      /// @return The extension type of the next header. If there are no more header extensions or if this object
274
      /// is empty a value of zero is returned
275
      uint8_t getNextExtensionHeaderType() const;
276
277
      /// @return An instance of this class representing the next extension header, if exists in the message. If
278
      /// there are no more header extensions or if this object is empty an empty instance of GtpExtension is
279
      /// returned, meaning one that GtpExtension#isNull() returns "true"
280
      GtpExtension getNextExtension() const;
281
    };  // GtpExtension
282
283
    ~GtpV1Layer() override = default;
284
285
    /// A constructor that creates the layer from an existing packet raw data
286
    /// @param[in] data A pointer to the raw data
287
    /// @param[in] dataLen Size of the data in bytes
288
    /// @param[in] prevLayer A pointer to the previous layer
289
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
290
    GtpV1Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
291
7.16k
        : Layer(data, dataLen, prevLayer, packet, GTPv1)
292
7.16k
    {}
293
294
    /// A constructor that creates a new GTPv1 layer and sets the message type and the TEID value
295
    /// @param[in] messageType The GTPv1 message type to be set in the newly created layer
296
    /// @param[in] teid The TEID value to be set in the newly created layer
297
    GtpV1Layer(GtpV1MessageType messageType, uint32_t teid);
298
299
    /// A constructor that creates a new GTPv1 layer and sets various parameters
300
    /// @param[in] messageType The GTPv1 message type to be set in the newly created layer
301
    /// @param[in] teid The TEID value to be set in the newly created layer
302
    /// @param[in] setSeqNum A flag indicating whether to set a sequence number. If set to "false" then the
303
    /// parameter "seqNum" will be ignored
304
    /// @param[in] seqNum The sequence number to be set in the newly created later. If "setSeqNum" is set to false
305
    /// this parameter will be ignored
306
    /// @param[in] setNpduNum A flag indicating whether to set the N-PDU number. If set to "false" then the
307
    /// parameter "npduNum" will be ignored
308
    /// @param[in] npduNum The N-PDU number to be set in the newly created later. If "setNpduNum" is set to false
309
    /// this parameter will be ignored
310
    GtpV1Layer(GtpV1MessageType messageType, uint32_t teid, bool setSeqNum, uint16_t seqNum, bool setNpduNum,
311
               uint8_t npduNum);
312
313
    /// A static method that takes a byte array and detects whether it is a GTP v1 message
314
    /// @param[in] data A byte array
315
    /// @param[in] dataSize The byte array size (in bytes)
316
    /// @return True if the data is identified as GTP v1 message (GTP-C or GTP-U)
317
    static bool isGTPv1(const uint8_t* data, size_t dataSize);
318
319
    /// @return The GTP v1 common header structure. Notice this points directly to the data, so every change will
320
    /// change the actual packet data
321
    gtpv1_header* getHeader() const
322
31.2k
    {
323
31.2k
      return reinterpret_cast<gtpv1_header*>(m_Data);
324
31.2k
    }
325
326
    /// Get the sequence number if exists on the message (sequence number is an optional field in GTP messages)
327
    /// @param[out] seqNumber Set with the sequence number value if exists in the layer. Otherwise remains unchanged
328
    /// @return True if the sequence number field exists in layer, in which case seqNumber is set with the value.
329
    /// Or false otherwise
330
    bool getSequenceNumber(uint16_t& seqNumber) const;
331
332
    /// Set a sequence number
333
    /// @param[in] seqNumber The sequence number to set
334
    /// @return True if the value was set successfully, false otherwise. In case of failure a corresponding error
335
    /// message will be written to log
336
    bool setSequenceNumber(uint16_t seqNumber);
337
338
    /// Get the N-PDU number if exists on the message (N-PDU number is an optional field in GTP messages)
339
    /// @param[out] npduNum Set with the N-PDU number value if exists in the layer. Otherwise remains unchanged
340
    /// @return True if the N-PDU number field exists in layer, in which case npduNum is set with the value.
341
    /// Or false otherwise
342
    bool getNpduNumber(uint8_t& npduNum) const;
343
344
    /// Set an N-PDU number
345
    /// @param[in] npduNum The N-PDU number to set
346
    /// @return True if the value was set successfully, false otherwise. In case of failure a corresponding error
347
    /// message will be written to log
348
    bool setNpduNumber(uint8_t npduNum);
349
350
    /// Get the type of the next header extension if exists on the message (extensions are optional in GTP messages)
351
    /// @param[out] nextExtType Set with the next header extension type if exists in layer. Otherwise remains
352
    /// unchanged
353
    /// @return True if the message contains header extensions, in which case nextExtType is set to the next
354
    /// header extension type. If there are no header extensions false is returned and nextExtType remains unchanged
355
    bool getNextExtensionHeaderType(uint8_t& nextExtType) const;
356
357
    /// @return An object that represents the next extension header, if exists in the message. If there are no
358
    /// extensions an empty object is returned, meaning an object which GtpExtension#isNull() returns "true"
359
    GtpExtension getNextExtension() const;
360
361
    /// Add a GTPv1 header extension. It is assumed that the extension is 4 bytes in length and its content is 2
362
    /// bytes in length. If you need a different content size please reach out to me. This method takes care of
363
    /// extending the layer to make room for the new extension and also sets the relevant flags and fields
364
    /// @param[in] extensionType The type of the new extension
365
    /// @param[in] extensionContent A 2-byte long content
366
    /// @return An object representing the newly added extension. If there was an error adding the extension a null
367
    /// object will be returned (meaning GtpExtension#isNull() will return "true") and a corresponding error message
368
    /// will be written to log
369
    GtpExtension addExtension(uint8_t extensionType, uint16_t extensionContent);
370
371
    /// @return The message type of this GTP packet
372
    GtpV1MessageType getMessageType() const;
373
374
    /// @return A string representation of the packet's message type
375
    std::string getMessageTypeAsString() const;
376
377
    /// @return True if this is a GTP-U message, false otherwise
378
    bool isGTPUMessage() const;
379
380
    /// @return True if this is a GTP-C message, false otherwise
381
    bool isGTPCMessage() const;
382
383
    /// A static method that checks whether the port is considered as GTPv1
384
    /// @param[in] port The port number to be checked
385
    /// @return True if the port matches those associated with the GTPv1 protocol
386
    static bool isGTPv1Port(uint16_t port)
387
88.0k
    {
388
88.0k
      return port == 2152 /* GTP-U */ || port == 2123 /* GTP-C */;
389
88.0k
    }
390
391
    // implement abstract methods
392
393
    /// Identifies the following next layers for GTP-U packets: IPv4Layer, IPv6Layer. Otherwise sets PayloadLayer
394
    void parseNextLayer() override;
395
396
    /// @return The size of the GTP header. For GTP-C packets the size is determined by the value of
397
    /// gtpv1_header#messageLength and for GTP-U the size only includes the GTP header itself (meaning
398
    /// the size of gtpv1_header plus the size of the optional fields such as sequence number, N-PDU
399
    /// or extensions if exist)
400
    size_t getHeaderLen() const override;
401
402
    /// Calculate the following fields:
403
    /// - gtpv1_header#messageLength
404
    void computeCalculateFields() override;
405
406
    std::string toString() const override;
407
408
    OsiModelLayer getOsiModelLayer() const override
409
1.25k
    {
410
1.25k
      return OsiModelTransportLayer;
411
1.25k
    }
412
  };
413
414
  /// @class GtpV2MessageType
415
  /// The enum wrapper class of GTPv2 message type
416
  class GtpV2MessageType
417
  {
418
  public:
419
    /// Define enum types and the corresponding int values
420
    enum Value : uint8_t
421
    {
422
      /// Unknown message
423
      Unknown = 0,
424
      /// Echo Request message
425
      EchoRequest = 1,
426
      /// Echo Response message
427
      EchoResponse = 2,
428
      /// Version Not Supported message
429
      VersionNotSupported = 3,
430
      /// Create Session Request message
431
      CreateSessionRequest = 32,
432
      /// Create Session Response message
433
      CreateSessionResponse = 33,
434
      /// Modify Bearer Request message
435
      ModifyBearerRequest = 34,
436
      /// Modify Bearer Response message
437
      ModifyBearerResponse = 35,
438
      /// Delete Session Request message
439
      DeleteSessionRequest = 36,
440
      /// Delete Session Response message
441
      DeleteSessionResponse = 37,
442
      /// Change Notification Request message
443
      ChangeNotificationRequest = 38,
444
      /// Change Notification Response message
445
      ChangeNotificationResponse = 39,
446
      /// Remote UE Report Notifications message
447
      RemoteUEReportNotifications = 40,
448
      /// Remote UE Report Acknowledge message
449
      RemoteUEReportAcknowledge = 41,
450
      /// Modify Bearer Command message
451
      ModifyBearerCommand = 64,
452
      /// Modify Bearer Failure message
453
      ModifyBearerFailure = 65,
454
      /// Delete Bearer Command message
455
      DeleteBearerCommand = 66,
456
      /// Delete Bearer Failure message
457
      DeleteBearerFailure = 67,
458
      /// Bearer Resource Command message
459
      BearerResourceCommand = 68,
460
      /// Bearer Resource Failure message
461
      BearerResourceFailure = 69,
462
      /// Downlink Data Notification Failure message
463
      DownlinkDataNotificationFailure = 70,
464
      /// Trace Session Activation message
465
      TraceSessionActivation = 71,
466
      /// Trace Session Deactivation message
467
      TraceSessionDeactivation = 72,
468
      /// Stop Paging Indication message
469
      StopPagingIndication = 73,
470
      /// Create Bearer Request message
471
      CreateBearerRequest = 95,
472
      /// Create Bearer Response message
473
      CreateBearerResponse = 96,
474
      /// Update Bearer Request message
475
      UpdateBearerRequest = 97,
476
      /// Update Bearer Response message
477
      UpdateBearerResponse = 98,
478
      /// Delete Bearer Request message
479
      DeleteBearerRequest = 99,
480
      /// Delete Bearer Response message
481
      DeleteBearerResponse = 100,
482
      /// Delete PDN Request message
483
      DeletePDNRequest = 101,
484
      /// Delete PDN Response message
485
      DeletePDNResponse = 102,
486
      /// PGW Downlink Notification message
487
      PGWDownlinkNotification = 103,
488
      /// PGW Downlink Acknowledge message
489
      PGWDownlinkAcknowledge = 104,
490
      /// Identification Request message
491
      IdentificationRequest = 128,
492
      /// Identification Response message
493
      IdentificationResponse = 129,
494
      /// Context Request message
495
      ContextRequest = 130,
496
      /// Context Response message
497
      ContextResponse = 131,
498
      /// Context Acknowledge message
499
      ContextAcknowledge = 132,
500
      /// Forward Relocation Request message
501
      ForwardRelocationRequest = 133,
502
      /// Forward Relocation Response message
503
      ForwardRelocationResponse = 134,
504
      /// Forward Relocation Notification message
505
      ForwardRelocationNotification = 135,
506
      /// Forward Relocation Acknowledge message
507
      ForwardRelocationAcknowledge = 136,
508
      /// Forward Access Notification message
509
      ForwardAccessNotification = 137,
510
      /// Forward Access Acknowledge message
511
      ForwardAccessAcknowledge = 138,
512
      /// Relocation Cancel Request message
513
      RelocationCancelRequest = 139,
514
      /// Relocation Cancel Response message
515
      RelocationCancelResponse = 140,
516
      /// Configuration Transfer Tunnel message
517
      ConfigurationTransferTunnel = 141,
518
      /// Detach Notification message
519
      DetachNotification = 149,
520
      /// Detach Acknowledge message
521
      DetachAcknowledge = 150,
522
      /// CS Paging message
523
      CSPaging = 151,
524
      /// RAN Information Relay message
525
      RANInformationRelay = 152,
526
      /// Alert MME Notification message
527
      AlertMMENotification = 153,
528
      /// Alert MME Acknowledge message
529
      AlertMMEAcknowledge = 154,
530
      /// UE Activity Notification message
531
      UEActivityNotification = 155,
532
      /// UE Activity Acknowledge message
533
      UEActivityAcknowledge = 156,
534
      /// ISR Status message
535
      ISRStatus = 157,
536
      /// Create Forwarding Request message
537
      CreateForwardingRequest = 160,
538
      /// Create Forwarding Response message
539
      CreateForwardingResponse = 161,
540
      /// Suspend Notification message
541
      SuspendNotification = 162,
542
      /// Suspend Acknowledge message
543
      SuspendAcknowledge = 163,
544
      /// Resume Notification message
545
      ResumeNotification = 164,
546
      /// Resume Acknowledge message
547
      ResumeAcknowledge = 165,
548
      /// Create Indirect Data Tunnel Request message
549
      CreateIndirectDataTunnelRequest = 166,
550
      /// Create Indirect Data Tunnel Response message
551
      CreateIndirectDataTunnelResponse = 167,
552
      /// Delete Indirect Data Tunnel Request message
553
      DeleteIndirectDataTunnelRequest = 168,
554
      /// Delete Indirect Data Tunnel Response message
555
      DeleteIndirectDataTunnelResponse = 169,
556
      /// Release Access Bearers Request message
557
      ReleaseAccessBearersRequest = 170,
558
      /// Release Access Bearers Response message
559
      ReleaseAccessBearersResponse = 171,
560
      /// Downlink Data Notification message
561
      DownlinkDataNotification = 176,
562
      /// Downlink Data Acknowledge message
563
      DownlinkDataAcknowledge = 177,
564
      /// PGW Restart Notification message
565
      PGWRestartNotification = 179,
566
      /// PGW Restart Acknowledge message
567
      PGWRestartAcknowledge = 180,
568
      /// Update PDN Connection Request message
569
      UpdatePDNConnectionRequest = 200,
570
      /// Update PDN Connection Response message
571
      UpdatePDNConnectionResponse = 201,
572
      /// Modify Access Bearers Request message
573
      ModifyAccessBearersRequest = 211,
574
      /// Modify Access Bearers Response message
575
      ModifyAccessBearersResponse = 212,
576
      /// MMBS Session Start Request message
577
      MMBSSessionStartRequest = 231,
578
      /// MMBS Session Start Response message
579
      MMBSSessionStartResponse = 232,
580
      /// MMBS Session Update Request message
581
      MMBSSessionUpdateRequest = 233,
582
      /// MMBS Session Update Response message
583
      MMBSSessionUpdateResponse = 234,
584
      /// MMBS Session Stop Request message
585
      MMBSSessionStopRequest = 235,
586
      /// MMBS Session Stop Response message
587
      MMBSSessionStopResponse = 236
588
    };
589
590
    GtpV2MessageType() = default;
591
592
    // cppcheck-suppress noExplicitConstructor
593
    /// Construct GtpV2MessageType from Value enum
594
    /// @param[in] value the message type enum value
595
164
    constexpr GtpV2MessageType(Value value) : m_Value(value)
596
164
    {}
597
598
    /// @return A string representation of the message type
599
    std::string toString() const;
600
601
    /// A static method that creates GtpV2MessageType from an integer value
602
    /// @param[in] value The message type integer value
603
    /// @return The message type that corresponds to the integer value. If the integer value
604
    /// doesn't corresponds to any message type, GtpV2MessageType::Unknown is returned
605
    static GtpV2MessageType fromUintValue(uint8_t value);
606
607
    // Allow switch and comparisons.
608
    constexpr operator Value() const
609
164
    {
610
164
      return m_Value;
611
164
    }
612
613
    // Prevent usage: if(GtpV2MessageType)
614
    explicit operator bool() const = delete;
615
616
  private:
617
    Value m_Value = GtpV2MessageType::Unknown;
618
  };
619
620
  /// @class GtpV2InformationElement
621
  /// A wrapper class for GTPv2 information elements (IE). This class does not create or modify IEs, but rather
622
  /// serves as a wrapper and provides useful methods for retrieving data from them
623
  class GtpV2InformationElement : public TLVRecord<uint8_t, uint16_t>
624
  {
625
  public:
626
    /// GTPv2 Information Element (IE) types as defined in 3GPP TS 29.274
627
    enum class Type : uint8_t
628
    {
629
      /// Unknown or reserved value
630
      Unknown = 0,
631
      /// International Mobile Subscriber Identity
632
      Imsi = 1,
633
      /// Indicates the result of a procedure
634
      Cause = 2,
635
      /// Recovery counter for GTP path management
636
      Recovery = 3,
637
      /// Session Transfer Number for SRVCC
638
      StnSr = 51,
639
      /// Access Point Name
640
      Apn = 71,
641
      /// Aggregate Maximum Bit Rate
642
      Ambr = 72,
643
      /// EPS Bearer ID
644
      Ebi = 73,
645
      /// IPv4/IPv6 Address
646
      IpAddress = 74,
647
      /// Mobile Equipment Identity (IMEI or IMEISV)
648
      Mei = 75,
649
      /// Mobile Station International Subscriber Directory Number
650
      Msisdn = 76,
651
      /// Indication flags for various features and capabilities
652
      Indication = 77,
653
      /// Protocol Configuration Options
654
      Pco = 78,
655
      /// PDN Address Allocation
656
      Paa = 79,
657
      /// Bearer Level Quality of Service
658
      BearerQos = 80,
659
      /// Flow Level Quality of Service
660
      FlowQos = 81,
661
      /// Radio Access Technology Type
662
      RatType = 82,
663
      /// Current PLMN and MME identifier
664
      ServingNetwork = 83,
665
      /// Bearer Traffic Flow Template
666
      BearerTft = 84,
667
      /// Traffic Aggregation Description
668
      Tad = 85,
669
      /// User Location Information
670
      Uli = 86,
671
      /// Fully Qualified TEID
672
      FTeid = 87,
673
      /// Temporary Mobile Subscriber Identity
674
      Tmsi = 88,
675
      /// Global Core Network ID
676
      GlobalCnId = 89,
677
      /// S103 PDN Data Forwarding Info
678
      S103PdnDataForwardingInfo = 90,
679
      /// S1-U Data Forwarding Info
680
      S1UDataForwardingInfo = 91,
681
      /// Delay Value in integer multiples of 50 milliseconds
682
      DelayValue = 92,
683
      /// Bearer Context
684
      BearerContext = 93,
685
      /// Charging ID for this PDP context
686
      ChargingId = 94,
687
      /// Charging Characteristics
688
      ChargingCharacteristics = 95,
689
      /// Trace Information
690
      TraceInformation = 96,
691
      /// Bearer Flags
692
      BearerFlags = 97,
693
      /// PDN Type (IPv4, IPv6, IPv4v6)
694
      PdnType = 99,
695
      /// Procedure Transaction ID
696
      Pti = 100,
697
      /// MM Context (GSM Key and Triplets)
698
      MmContext1 = 103,
699
      /// MM Context (UMTS Key, Used Cipher and Quintuplets)
700
      MmContext2 = 104,
701
      /// MM Context (GSM Key, Used Cipher and Quintuplets)
702
      MmContext3 = 105,
703
      /// MM Context (UMTS Key and Quintuplets)
704
      MmContext4 = 106,
705
      /// MM Context (EPS Security Context, Quadruplets and Quintuplets)
706
      MmContext5 = 107,
707
      /// MM Context (UMTS Key, Quadruplets and Quintuplets)
708
      MmContext6 = 108,
709
      /// PDN Connection
710
      PdnConnection = 109,
711
      /// PDU Numbers
712
      PduNumbers = 110,
713
      /// Packet TMSI
714
      PTmsi = 111,
715
      /// P-TMSI Signature
716
      PTmsiSignature = 112,
717
      /// Hop Counter
718
      HopCounter = 113,
719
      /// UE Time Zone
720
      UeTimeZone = 114,
721
      /// Trace Reference
722
      TraceReference = 115,
723
      /// Complete Request Message
724
      CompleteRequestMessage = 116,
725
      /// Globally Unique Temporary Identity
726
      Guti = 117,
727
      /// F-Container
728
      FContainer = 118,
729
      /// F-Cause
730
      FCause = 119,
731
      /// PLMN Identity
732
      PlmnId = 120,
733
      /// Target Identification
734
      TargetIdentification = 121,
735
      /// Packet Flow ID
736
      PacketFlowId = 123,
737
      /// RAB Context
738
      RabContext = 124,
739
      /// Source RNC PDCP Context Info
740
      SourceRncPdcpContextInfo = 125,
741
      /// Port Number
742
      PortNumber = 126,
743
      /// APN Restriction
744
      ApnRestriction = 127,
745
      /// Selection Mode
746
      SelectionMode = 128,
747
      /// Source Identification
748
      SourceIdentification = 129,
749
      /// Change Reporting Action
750
      ChangeReportingAction = 131,
751
      /// Fully Qualified PDN Connection Set Identifier
752
      FqCsid = 132,
753
      /// Channel Needed
754
      ChannelNeeded = 133,
755
      /// eMLPP Priority
756
      EmlppPriority = 134,
757
      /// Node Type
758
      NodeType = 135,
759
      /// Fully Qualified Domain Name
760
      Fqdn = 136,
761
      /// Transaction Identifier
762
      Ti = 137,
763
      /// MBMS Session Duration
764
      MbmsSessionDuration = 138,
765
      /// MBMS Service Area
766
      MbmsServiceArea = 139,
767
      /// MBMS Session Identifier
768
      MbmsSessionIdentifier = 140,
769
      /// MBMS Flow Identifier
770
      MbmsFlowIdentifier = 141,
771
      /// MBMS IP Multicast Distribution
772
      MbmsIpMulticastDistribution = 142,
773
      /// MBMS Distribution Acknowledge
774
      MbmsDistributionAcknowledge = 143,
775
      /// RF Selection Priority Index
776
      RfspIndex = 144,
777
      /// User CSG Information
778
      Uci = 145,
779
      /// CSG Information Reporting Action
780
      CsgInformationReportingAction = 146,
781
      /// CSG ID
782
      CsgId = 147,
783
      /// CSG Membership Indication
784
      Cmi = 148,
785
      /// Service Indicator
786
      ServiceIndicator = 149,
787
      /// Detach Type
788
      DetachType = 150,
789
      /// Local Distinguished Name
790
      Ldn = 151,
791
      /// Node Features
792
      NodeFeatures = 152,
793
      /// MBMS Time To Data Transfer
794
      MbmsTimeToDataTransfer = 153,
795
      /// Throttling
796
      Throttling = 154,
797
      /// Allocation Retention Priority
798
      Arp = 155,
799
      /// EPC Timer
800
      EpcTimer = 156,
801
      /// Signalling Priority Indication
802
      SignallingPriorityIndication = 157,
803
      /// Temporary Mobile Group Identity
804
      Tmgi = 158,
805
      /// Additional MM Context For SRVCC
806
      AdditionalMmContextForSrvcc = 159,
807
      /// Additional Flags For SRVCC
808
      AdditionalFlagsForSrvcc = 160,
809
      /// MDT Configuration
810
      MdtConfiguration = 162,
811
      /// Additional Protocol Configuration Options
812
      Apco = 163,
813
      /// Absolute Time of MBMS Data Transfer
814
      AbsoluteTimeOfMbmsDataTransfer = 164,
815
      /// H(e)NB Information Reporting
816
      HenbInformationReporting = 165,
817
      /// IPv4 Configuration Parameters
818
      Ipv4ConfigurationParameters = 166,
819
      /// Change To Report Flags
820
      ChangeToReportFlags = 167,
821
      /// Action Indication
822
      ActionIndication = 168,
823
      /// TWAN Identifier
824
      TwanIdentifier = 169,
825
      /// ULI Timestamp
826
      UliTimestamp = 170,
827
      /// MBMS Flags
828
      MbmsFlags = 171,
829
      /// RAN/NAS Cause
830
      RanNasCause = 172,
831
      /// CN Operator Selection Entity
832
      CnOperatorSelectionEntity = 173,
833
      /// Trusted WLAN Mode Indication
834
      Twmi = 174,
835
      /// Node Number
836
      NodeNumber = 175,
837
      /// Node Identifier
838
      NodeIdentifier = 176,
839
      /// Presence Reporting Area Action
840
      PresenceReportingAreaAction = 177,
841
      /// Presence Reporting Area Information
842
      PresenceReportingAreaInformation = 178,
843
      /// TWAN Identifier Timestamp
844
      TwanIdentifierTimestamp = 179,
845
      /// Overload Control Information
846
      OverloadControlInformation = 180,
847
      /// Load Control Information
848
      LoadControlInformation = 181,
849
      /// Metric
850
      Metric = 182,
851
      /// Sequence Number
852
      SequenceNumber = 183,
853
      /// APN and Relative Capacity
854
      ApnAndRelativeCapacity = 184,
855
      /// WLAN Offloadability Indication
856
      WlanOffloadabilityIndication = 185,
857
      /// Paging and Service Information
858
      PagingAndServiceInformation = 186,
859
      /// Integer Number
860
      IntegerNumber = 187,
861
      /// Millisecond Time Stamp
862
      MillisecondTimeStamp = 188,
863
      /// Monitoring Event Information
864
      MonitoringEventInformation = 189,
865
      /// ECGI List
866
      EcgiList = 190,
867
      /// Remote UE Context
868
      RemoteUeContext = 191,
869
      /// Remote User ID
870
      RemoteUserId = 192,
871
      /// Remote UE IP Information
872
      RemoteUeIpInformation = 193,
873
      /// CIoT Optimizations Support Indication
874
      CiotOptimizationsSupportIndication = 194,
875
      /// SCEF PDN Connection
876
      ScefPdnConnection = 195,
877
      /// Header Compression Configuration
878
      HeaderCompressionConfiguration = 196,
879
      /// Extended Protocol Configuration Options
880
      ExtendedPco = 197,
881
      /// Serving PLMN Rate Control
882
      ServingPlmnRateControl = 198,
883
      /// Counter
884
      Counter = 199,
885
      /// Mapped UE Usage Type
886
      MappedUeUsageType = 200,
887
      /// Secondary RAT Usage Data Report
888
      SecondaryRatUsageDataReport = 201,
889
      /// UP Function Selection Indication Flags
890
      UpFunctionSelectionIndicationFlags = 202,
891
      /// Maximum Packet Loss Rate
892
      MaximumPacketLossRate = 203,
893
      /// APN Rate Control Status
894
      ApnRateControlStatus = 204,
895
      /// Extended Trace Information
896
      ExtendedTraceInformation = 205,
897
      /// Monitoring Event Extension Information
898
      MonitoringEventExtensionInformation = 206,
899
      /// Additional RRM Policy Index
900
      AdditionalRrmPolicyIndex = 207,
901
      /// V2X Context
902
      V2xContext = 208,
903
      /// PC5 QoS Parameters
904
      Pc5QosParameters = 209,
905
      /// Services Authorized
906
      ServicesAuthorized = 210,
907
      /// Bit Rate
908
      BitRate = 211,
909
      /// PC5 QoS Flow
910
      Pc5QosFlow = 212,
911
      /// SGi PtP Tunnel Address
912
      SgiPtpTunnelAddress = 213
913
    };
914
915
    /// A c'tor for this class that gets a pointer to the IE raw data (byte array)
916
    /// @param[in] infoElementRawData A pointer to the IE raw data
917
    explicit GtpV2InformationElement(uint8_t* infoElementRawData) : TLVRecord(infoElementRawData)
918
0
    {}
919
920
    ~GtpV2InformationElement() override = default;
921
922
    /// @return The information element (IE) type
923
    GtpV2InformationElement::Type getIEType();
924
925
    /// @return The IE CR flag
926
    uint8_t getCRFlag();
927
928
    /// @return The IE instance value
929
    uint8_t getInstance();
930
931
    // implement abstract methods
932
933
    size_t getValueOffset() const override
934
0
    {
935
0
      return sizeof(uint8_t);
936
0
    }
937
938
    size_t getTotalSize() const override;
939
940
    size_t getDataSize() const override;
941
  };
942
943
  /// @class GtpV2InformationElementBuilder
944
  /// A class for building GTPv2 information elements (IE). This builder receives the IE parameters in its c'tor,
945
  /// builds the IE raw buffer and provides a build() method to get a GtpV2InformationElement object out of it
946
  class GtpV2InformationElementBuilder : public TLVRecordBuilder
947
  {
948
  public:
949
    /// A c'tor for building information elements (IE) which their value is a byte array. The
950
    /// GtpV2InformationElement object can be later retrieved by calling build().
951
    /// @param[in] infoElementType Information elements (IE) type
952
    /// @param[in] crFlag CR flag value
953
    /// @param[in] instance Instance value
954
    /// @param[in] infoElementValue A byte array of the IE value
955
    GtpV2InformationElementBuilder(GtpV2InformationElement::Type infoElementType, const std::bitset<4>& crFlag,
956
                                   const std::bitset<4>& instance, const std::vector<uint8_t>& infoElementValue);
957
958
    /// Build the GtpV2InformationElement object out of the parameters defined in the c'tor
959
    /// @return The GtpV2InformationElement object
960
    GtpV2InformationElement build() const;
961
962
  private:
963
    std::bitset<4> m_CRFlag;
964
    std::bitset<4> m_Instance;
965
  };
966
967
  /// @class GtpV2Layer
968
  /// A class representing the GTPv2 defined in 3GPP TS 29.274
969
  class GtpV2Layer : public Layer
970
  {
971
  public:
972
0
    ~GtpV2Layer() override = default;
973
974
    /// A constructor that creates the layer from an existing packet raw data
975
    /// @param[in] data A pointer to the raw data
976
    /// @param[in] dataLen Size of the data in bytes
977
    /// @param[in] prevLayer A pointer to the previous layer
978
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
979
    GtpV2Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
980
        : Layer(data, dataLen, prevLayer, packet, GTPv2)
981
0
    {}
982
983
    /// A constructor that creates a new GTPv2 message
984
    /// @param messageType GTPv2 message type
985
    /// @param sequenceNumber Message sequence number
986
    /// @param setTeid Whether or not to set Tunnel Endpoint Identifier in this message
987
    /// @param teid Tunnel Endpoint Identifier value. Only used if setTeid is set to true
988
    /// @param setMessagePriority Whether or not to set Message Priority in this message
989
    /// @param messagePriority Message Priority. Only used if setMessagePriority to true
990
    GtpV2Layer(GtpV2MessageType messageType, uint32_t sequenceNumber, bool setTeid = false, uint32_t teid = 0,
991
               bool setMessagePriority = false, std::bitset<4> messagePriority = 0);
992
993
    /// A static method that checks whether the port is considered as GTPv2
994
    /// @param[in] port The port number to be checked
995
    /// @return True if the port matches those associated with the GTPv2 protocol
996
    static bool isGTPv2Port(uint16_t port)
997
147k
    {
998
147k
      return port == 2123;
999
147k
    }
1000
1001
    /// A static method that takes a byte array and detects whether it is a GTPv2 message
1002
    /// @param[in] data A byte array
1003
    /// @param[in] dataSize The byte array size (in bytes)
1004
    /// @return True if the data is identified as GTPv2 message
1005
    static bool isDataValid(const uint8_t* data, size_t dataSize);
1006
1007
    /// @return The message type
1008
    GtpV2MessageType getMessageType() const;
1009
1010
    /// Set message type
1011
    /// @param type The message type to set
1012
    void setMessageType(const GtpV2MessageType& type);
1013
1014
    /// @return The message length as set in the layer. Note it is different from getHeaderLen() because the later
1015
    /// refers to the entire layers length, and this property excludes the mandatory part of the GTP-C header
1016
    /// (the first 4 octets)
1017
    uint16_t getMessageLength() const;
1018
1019
    /// @return True if there is another GTPv2 message piggybacking on this message (will appear as another
1020
    /// GtpV2Layer after this layer)
1021
    bool isPiggybacking() const;
1022
1023
    /// Get the Tunnel Endpoint Identifier (TEID) if exists
1024
    /// @return A pair of 2 values; the first value states whether TEID exists, and if it's true the second value
1025
    /// contains the TEID value
1026
    std::pair<bool, uint32_t> getTeid() const;
1027
1028
    /// Set Tunnel Endpoint Identifier (TEID)
1029
    /// @param teid The TEID value to set
1030
    void setTeid(uint32_t teid);
1031
1032
    /// Unset Tunnel Endpoint Identifier (TEID) if exists in the layer (otherwise does nothing)
1033
    void unsetTeid();
1034
1035
    /// @return The sequence number
1036
    uint32_t getSequenceNumber() const;
1037
1038
    /// Set the sequence number
1039
    /// @param sequenceNumber The sequence number value to set
1040
    void setSequenceNumber(uint32_t sequenceNumber);
1041
1042
    /// Get the Message Property if exists
1043
    /// @return A pair of 2 values; the first value states whether Message Priority exists, and if it's true
1044
    /// the second value contains the Message Priority value
1045
    std::pair<bool, uint8_t> getMessagePriority() const;
1046
1047
    /// Set Message Priority
1048
    /// @param messagePriority The Message Priority value to set
1049
    void setMessagePriority(const std::bitset<4>& messagePriority);
1050
1051
    /// Unset Message Priority if exists in the layer (otherwise does nothing)
1052
    void unsetMessagePriority();
1053
1054
    /// @return The first GTPv2 Information Element (IE). If there are no IEs the returned value will contain
1055
    /// a logical null (GtpV2InformationElement#isNull() == true)
1056
    GtpV2InformationElement getFirstInformationElement() const;
1057
1058
    /// Get the GTPv2 Information Element (IE) that comes after a given IE. If the given IE was the last one, the
1059
    /// returned value will contain a logical null (GtpV2InformationElement#isNull() == true)
1060
    /// @param[in] infoElement A given GTPv2 Information Element
1061
    /// @return A GtpV2InformationElement object containing the IE that comes next, or logical null if the given
1062
    /// IE: (1) is the last one; (2) contains a logical null or (3) doesn't belong to this packet
1063
    GtpV2InformationElement getNextInformationElement(GtpV2InformationElement infoElement) const;
1064
1065
    /// Get a GTPv2 Information Element (IE) by type
1066
    /// @param[in] infoElementType GTPv2 Information Element (IE) type
1067
    /// @return A GtpV2InformationElement object containing the first IE that matches this type, or logical
1068
    /// null (GtpV2InformationElement#isNull() == true) if no such IE found
1069
    GtpV2InformationElement getInformationElement(GtpV2InformationElement::Type infoElementType) const;
1070
1071
    /// @return The number of GTPv2 Information Elements (IEs) in this layer
1072
    size_t getInformationElementCount() const;
1073
1074
    /// Add a new Information Element (IE) at the end of the layer
1075
    /// @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested
1076
    /// IE data to add
1077
    /// @return A GtpV2InformationElement object containing the newly added IE data or logical null
1078
    /// (GtpV2InformationElement#isNull() == true) if addition failed
1079
    GtpV2InformationElement addInformationElement(const GtpV2InformationElementBuilder& infoElementBuilder);
1080
1081
    /// Add a new Information Element (IE) after an existing one
1082
    /// @param[in] infoElementBuilder A GtpV2InformationElementBuilder object that contains the requested
1083
    /// IE data to add
1084
    /// @param[in] infoElementType The IE type which the newly added option will come after
1085
    /// @return A GtpV2InformationElement object containing the newly added IE data or logical null
1086
    /// (GtpV2InformationElement#isNull() == true) if addition failed
1087
    GtpV2InformationElement addInformationElementAfter(const GtpV2InformationElementBuilder& infoElementBuilder,
1088
                                                       GtpV2InformationElement::Type infoElementType);
1089
1090
    /// Remove an existing Information Element (IE) from the layer
1091
    /// @param[in] infoElementType The IE type to remove
1092
    /// @return True if the IE was successfully removed or false if type wasn't found or if removal failed
1093
    bool removeInformationElement(GtpV2InformationElement::Type infoElementType);
1094
1095
    /// Remove all Information Elements (IE) in this layer
1096
    /// @return True if all IEs were successfully removed or false if removal failed for some reason
1097
    bool removeAllInformationElements();
1098
1099
    // implement abstract methods
1100
1101
    /// Identifies if the next layer is GTPv2 piggyback. Otherwise sets PayloadLayer
1102
    void parseNextLayer() override;
1103
1104
    /// @return The size of the GTPv2 header including its Information Elements (IE)
1105
    size_t getHeaderLen() const override;
1106
1107
    /// Computes the piggybacking flag by checking if the next layer is also a GTPv2 message
1108
    void computeCalculateFields() override;
1109
1110
    std::string toString() const override;
1111
1112
    OsiModelLayer getOsiModelLayer() const override
1113
0
    {
1114
0
      return OsiModelTransportLayer;
1115
0
    }
1116
1117
  private:
1118
#pragma pack(push, 1)
1119
    struct gtpv2_basic_header
1120
    {
1121
#if (BYTE_ORDER == LITTLE_ENDIAN)
1122
      uint8_t unused : 2, messagePriorityPresent : 1, teidPresent : 1, piggybacking : 1, version : 3;
1123
#else
1124
      uint8_t version : 3, piggybacking : 1, teidPresent : 1, messagePriorityPresent : 1, unused : 2;
1125
#endif
1126
      uint8_t messageType;
1127
      uint16_t messageLength;
1128
    };
1129
#pragma pack(pop)
1130
1131
    TLVRecordReader<GtpV2InformationElement> m_IEReader;
1132
1133
    gtpv2_basic_header* getHeader() const
1134
0
    {
1135
0
      return reinterpret_cast<gtpv2_basic_header*>(m_Data);
1136
0
    }
1137
1138
    uint8_t* getIEBasePtr() const;
1139
1140
    GtpV2InformationElement addInformationElementAt(const GtpV2InformationElementBuilder& infoElementBuilder,
1141
                                                    int offset);
1142
  };
1143
}  // namespace pcpp