/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 |