/src/PcapPlusPlus/Packet++/header/PostgresLayer.h
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | #include "Layer.h" |
4 | | #include "PointerVector.h" |
5 | | #include <memory> |
6 | | #include <ostream> |
7 | | #include <unordered_map> |
8 | | |
9 | | /// @file |
10 | | |
11 | | /// @namespace pcpp |
12 | | /// @brief The main namespace for the PcapPlusPlus lib |
13 | | namespace pcpp |
14 | | { |
15 | | |
16 | | /// @enum PostgresMessageOrigin |
17 | | /// Indicates whether the message is from the frontend (client) or backend (server) |
18 | | enum class PostgresMessageOrigin |
19 | | { |
20 | | Frontend, |
21 | | Backend |
22 | | }; |
23 | | |
24 | | /// @class PostgresMessageType |
25 | | /// Represents PostgreSQL message types (both frontend and backend) |
26 | | class PostgresMessageType |
27 | | { |
28 | | public: |
29 | | /// Define enum types for all PostgreSQL message types |
30 | | enum Value : uint8_t |
31 | | { |
32 | | // Frontend (client) message types |
33 | | |
34 | | /// Startup message (first message in connection) |
35 | | Frontend_StartupMessage, |
36 | | /// SSL request code (sent by client to request SSL) |
37 | | Frontend_SSLRequest, |
38 | | /// Cancel request (sent by client to cancel a running query) |
39 | | Frontend_CancelRequest, |
40 | | /// GSSAPI encryption request |
41 | | Frontend_GSSENCRequest, |
42 | | /// Simple query message |
43 | | Frontend_Query, |
44 | | /// Parse message (prepared statement) |
45 | | Frontend_Parse, |
46 | | /// Bind message (portal binding) |
47 | | Frontend_Bind, |
48 | | /// Execute message (portal execution) |
49 | | Frontend_Execute, |
50 | | /// Close message (close a prepared statement or portal) |
51 | | Frontend_Close, |
52 | | /// Describe message (describe a prepared statement or portal) |
53 | | Frontend_Describe, |
54 | | /// Function call message |
55 | | Frontend_FunctionCall, |
56 | | /// Flush message |
57 | | Frontend_Flush, |
58 | | /// Sync message (sync after batch) |
59 | | Frontend_Sync, |
60 | | /// Copy data message (during COPY) |
61 | | Frontend_CopyData, |
62 | | /// Copy done message (during COPY) |
63 | | Frontend_CopyDone, |
64 | | /// Copy fail message (during COPY) |
65 | | Frontend_CopyFail, |
66 | | /// Terminate message (disconnect) |
67 | | Frontend_Terminate, |
68 | | /// Unknown frontend message type |
69 | | Frontend_Unknown, |
70 | | |
71 | | // Backend (server) message types |
72 | | |
73 | | /// Authentication successful |
74 | | Backend_AuthenticationOk, |
75 | | /// Authentication using Kerberos V4 |
76 | | Backend_AuthenticationKerberosV4, |
77 | | /// Authentication using Kerberos V5 |
78 | | Backend_AuthenticationKerberosV5, |
79 | | /// Authentication using cleartext password |
80 | | Backend_AuthenticationCleartextPassword, |
81 | | /// Authentication using MD5 password |
82 | | Backend_AuthenticationMD5Password, |
83 | | /// Authentication using GSSAPI |
84 | | Backend_AuthenticationGSS, |
85 | | /// GSSAPI authentication continues |
86 | | Backend_AuthenticationGSSContinue, |
87 | | /// Authentication using SSPI |
88 | | Backend_AuthenticationSSPI, |
89 | | /// SASL authentication mechanism list |
90 | | Backend_AuthenticationSASL, |
91 | | /// SASL authentication continues |
92 | | Backend_AuthenticationSASLContinue, |
93 | | /// SASL authentication final message |
94 | | Backend_AuthenticationSASLFinal, |
95 | | /// Backend key data (secret key for cancel) |
96 | | Backend_BackendKeyData, |
97 | | /// Bind complete |
98 | | Backend_BindComplete, |
99 | | /// Close complete |
100 | | Backend_CloseComplete, |
101 | | /// Command complete (after query execution) |
102 | | Backend_CommandComplete, |
103 | | /// Copy data (during COPY) |
104 | | Backend_CopyData, |
105 | | /// Copy done (during COPY) |
106 | | Backend_CopyDone, |
107 | | /// Copy in response (during COPY from client) |
108 | | Backend_CopyInResponse, |
109 | | /// Copy out response (during COPY to client) |
110 | | Backend_CopyOutResponse, |
111 | | /// Copy both response (during COPY bidirectional) |
112 | | Backend_CopyBothResponse, |
113 | | /// Data row (result set) |
114 | | Backend_DataRow, |
115 | | /// Empty query response |
116 | | Backend_EmptyQueryResponse, |
117 | | /// Error response |
118 | | Backend_ErrorResponse, |
119 | | /// Function call response |
120 | | Backend_FunctionCallResponse, |
121 | | /// Negotiate protocol version |
122 | | Backend_NegotiateProtocolVersion, |
123 | | /// No data (for queries that don't return rows) |
124 | | Backend_NoData, |
125 | | /// Notice response (warning) |
126 | | Backend_NoticeResponse, |
127 | | /// Notification response (LISTEN/NOTIFY) |
128 | | Backend_NotificationResponse, |
129 | | /// Parameter description (for prepared statements) |
130 | | Backend_ParameterDescription, |
131 | | /// Parameter status (runtime parameter setting) |
132 | | Backend_ParameterStatus, |
133 | | /// Parse complete |
134 | | Backend_ParseComplete, |
135 | | /// Portal suspended (during cursor fetch) |
136 | | Backend_PortalSuspended, |
137 | | /// Ready for query (idle state) |
138 | | Backend_ReadyForQuery, |
139 | | /// Row description (column definitions) |
140 | | Backend_RowDescription, |
141 | | /// Unknown backend message type |
142 | | Backend_Unknown, |
143 | | }; |
144 | | |
145 | | constexpr PostgresMessageType() : m_Value(Frontend_Unknown) |
146 | 0 | {} |
147 | | |
148 | | // cppcheck-suppress noExplicitConstructor |
149 | | /// @brief Constructs a PostgresMessageType object from a Value enum |
150 | | /// @param[in] value The Value enum value |
151 | 69 | constexpr PostgresMessageType(Value value) : m_Value(value) |
152 | 69 | {} |
153 | | |
154 | | /// @brief Converts the message type to its character representation |
155 | | /// @return The message type character |
156 | | char toChar() const; |
157 | | |
158 | | /// @brief Returns a string representation of the message type |
159 | | /// @return A string representation of the message type |
160 | | std::string toString() const; |
161 | | |
162 | | /// @brief Stream operator for PostgresMessageType |
163 | | /// @param[in] os The output stream |
164 | | /// @param[in] messageType The message type to print |
165 | | /// @return The output stream |
166 | | friend std::ostream& operator<<(std::ostream& os, const PostgresMessageType& messageType) |
167 | 0 | { |
168 | 0 | os << messageType.toString(); |
169 | 0 | return os; |
170 | 0 | } |
171 | | |
172 | | /// @brief Converts the message type to a string |
173 | | /// @return The message type as a string |
174 | | explicit operator std::string() const |
175 | 0 | { |
176 | 0 | return toString(); |
177 | 0 | } |
178 | | |
179 | | /// @brief Returns the origin of the message (frontend or backend) |
180 | | /// @return The message origin |
181 | | PostgresMessageOrigin getOrigin() const; |
182 | | |
183 | | // Allow switch and comparisons |
184 | | constexpr operator Value() const |
185 | 0 | { |
186 | 0 | return m_Value; |
187 | 0 | } |
188 | | |
189 | | // Prevent usage: if(PostgresMessageType) |
190 | | explicit operator bool() const = delete; |
191 | | |
192 | | private: |
193 | | Value m_Value; |
194 | | }; |
195 | | |
196 | | /// @class PostgresMessage |
197 | | /// Represents a PostgreSQL message (base class) |
198 | | class PostgresMessage |
199 | | { |
200 | | public: |
201 | 69 | virtual ~PostgresMessage() = default; |
202 | | |
203 | | /// @brief Parse a PostgreSQL backend message from raw data |
204 | | /// @param[in] data A pointer to the raw data |
205 | | /// @param[in] dataLen Size of the data in bytes |
206 | | /// @return A unique pointer to the parsed PostgresMessage, or nullptr if parsing fails |
207 | | static std::unique_ptr<PostgresMessage> parsePostgresBackendMessage(const uint8_t* data, size_t dataLen); |
208 | | |
209 | | /// @brief Parse a PostgreSQL frontend message from raw data |
210 | | /// @param[in] data A pointer to the raw data |
211 | | /// @param[in] dataLen Size of the data in bytes |
212 | | /// @return A unique pointer to the parsed PostgresMessage, or nullptr if parsing fails |
213 | | static std::unique_ptr<PostgresMessage> parsePostgresFrontendMessage(const uint8_t* data, size_t dataLen); |
214 | | |
215 | | /// @return The message type |
216 | | PostgresMessageType getMessageType() const |
217 | 0 | { |
218 | 0 | return m_MessageType; |
219 | 0 | } |
220 | | |
221 | | /// @return The message origin (frontend or backend) |
222 | | PostgresMessageOrigin getMessageOrigin() const |
223 | 0 | { |
224 | 0 | return m_MessageType.getOrigin(); |
225 | 0 | } |
226 | | |
227 | | /// @brief Returns the length of the message payload |
228 | | /// @return The message length. If the first byte the message starts is 0, with length (no message type) |
229 | | uint32_t getMessageLength() const; |
230 | | |
231 | | /// @brief Returns the total length of the message including the length field |
232 | | /// @return The total message length in bytes |
233 | | size_t getTotalMessageLength() const |
234 | 138 | { |
235 | 138 | return m_DataLen; |
236 | 138 | } |
237 | | |
238 | | /// @brief Returns the raw payload bytes of the message |
239 | | /// @return The raw payload bytes of the message |
240 | | std::vector<uint8_t> getRawPayload() const; |
241 | | |
242 | | protected: |
243 | | PostgresMessage(const uint8_t* data, size_t dataLen, const PostgresMessageType& messageType) |
244 | 69 | : m_Data(data), m_DataLen(dataLen), m_MessageType(messageType) |
245 | 69 | {} |
246 | | |
247 | | const uint8_t* m_Data; |
248 | | size_t m_DataLen; |
249 | | PostgresMessageType m_MessageType; |
250 | | }; |
251 | | |
252 | | /// @class PostgresStartupMessage |
253 | | /// Represents a PostgreSQL StartupMessage |
254 | | class PostgresStartupMessage : public PostgresMessage |
255 | | { |
256 | | public: |
257 | | /// A map of parameter name to value |
258 | | using ParameterMap = std::unordered_map<std::string, std::string>; |
259 | | |
260 | | /// A constructor that creates the layer from an existing packet raw data |
261 | | /// @param[in] data A pointer to the raw data |
262 | | /// @param[in] dataLen Size of the data in bytes |
263 | | PostgresStartupMessage(const uint8_t* data, size_t dataLen) |
264 | 2 | : PostgresMessage(data, dataLen, PostgresMessageType::Frontend_StartupMessage) |
265 | 2 | {} |
266 | | |
267 | | /// @return The protocol version (major version in high 16 bits, minor version in low 16 bits) |
268 | | uint32_t getProtocolVersion() const; |
269 | | |
270 | | /// @return The major protocol version number |
271 | | uint16_t getProtocolMajorVersion() const; |
272 | | |
273 | | /// @return The minor protocol version number |
274 | | uint16_t getProtocolMinorVersion() const; |
275 | | |
276 | | /// @return The parameter name/value pairs as a map |
277 | | const ParameterMap& getParameters() const; |
278 | | |
279 | | /// @return The value of a specific parameter, or empty string if not found |
280 | | std::string getParameter(const std::string& name) const; |
281 | | |
282 | | private: |
283 | | static constexpr size_t ProtocolVersionOffset = 4; |
284 | | static constexpr size_t MinStartupMessageLength = 8; |
285 | | |
286 | | mutable ParameterMap m_Parameters; |
287 | | mutable bool m_ParametersParsed = false; |
288 | | |
289 | | std::string readString(size_t offset) const; |
290 | | }; |
291 | | |
292 | | /// @class PostgresParameterStatus |
293 | | /// Represents a PostgreSQL ParameterStatus message |
294 | | class PostgresParameterStatus : public PostgresMessage |
295 | | { |
296 | | public: |
297 | | /// A constructor that creates the layer from an existing packet raw data |
298 | | /// @param[in] data A pointer to the raw data |
299 | | /// @param[in] dataLen Size of the data in bytes |
300 | | PostgresParameterStatus(const uint8_t* data, size_t dataLen) |
301 | 46 | : PostgresMessage(data, dataLen, PostgresMessageType::Backend_ParameterStatus) |
302 | 46 | {} |
303 | | |
304 | | /// @return The parameter name |
305 | | std::string getParameterName() const; |
306 | | |
307 | | /// @return The parameter value |
308 | | std::string getParameterValue() const; |
309 | | }; |
310 | | |
311 | | /// @class PostgresQueryMessage |
312 | | /// Represents a PostgreSQL Query message (Frontend) |
313 | | class PostgresQueryMessage : public PostgresMessage |
314 | | { |
315 | | public: |
316 | | /// A constructor that creates the layer from an existing packet raw data |
317 | | /// @param[in] data A pointer to the raw data |
318 | | /// @param[in] dataLen Size of the data in bytes |
319 | | PostgresQueryMessage(const uint8_t* data, size_t dataLen) |
320 | 0 | : PostgresMessage(data, dataLen, PostgresMessageType::Frontend_Query) |
321 | 0 | {} |
322 | | |
323 | | /// @return The SQL query string |
324 | | std::string getQuery() const; |
325 | | }; |
326 | | |
327 | | /// @class PostgresRowDescriptionMessage |
328 | | /// Represents a PostgreSQL RowDescription message (backend) |
329 | | class PostgresRowDescriptionMessage : public PostgresMessage |
330 | | { |
331 | | public: |
332 | | /// @enum PostgresColumnFormat |
333 | | /// Represents the format of a column in a PostgreSQL RowDescription message. |
334 | | /// PostgreSQL supports two formats: text (0) and binary (1). |
335 | | enum class PostgresColumnFormat |
336 | | { |
337 | | /// Text format (format code 0) |
338 | | Text = 0, |
339 | | /// Binary format (format code 1) |
340 | | Binary = 1, |
341 | | /// Unknown format (format code >= 2) |
342 | | Unknown = 2 |
343 | | }; |
344 | | |
345 | | /// @struct PostgresColumnInfo |
346 | | /// Represents metadata for a single column in a RowDescription message |
347 | | struct PostgresColumnInfo |
348 | | { |
349 | | /// Column name |
350 | | std::string name; |
351 | | /// Table OID (0 if not from a table column) |
352 | | uint32_t tableOID; |
353 | | /// Column index within the table |
354 | | uint16_t columnIndex; |
355 | | /// Data type OID |
356 | | uint32_t typeOID; |
357 | | /// Type size (-1 for variable length) |
358 | | int16_t typeSize; |
359 | | /// Type modifier (-1 if none) |
360 | | int32_t typeModifier; |
361 | | /// Format |
362 | | PostgresColumnFormat format; |
363 | | }; |
364 | | |
365 | | /// A constructor that creates the layer from an existing packet raw data |
366 | | /// @param[in] data A pointer to the raw data |
367 | | /// @param[in] dataLen Size of the data in bytes |
368 | | PostgresRowDescriptionMessage(const uint8_t* data, size_t dataLen) |
369 | 0 | : PostgresMessage(data, dataLen, PostgresMessageType::Backend_RowDescription) |
370 | 0 | {} |
371 | | |
372 | | /// @return Vector of column metadata |
373 | | std::vector<PostgresColumnInfo> getColumnInfos() const; |
374 | | }; |
375 | | |
376 | | /// @class PostgresDataRowMessage |
377 | | /// Represents a PostgreSQL DataRow message (backend) |
378 | | class PostgresDataRowMessage : public PostgresMessage |
379 | | { |
380 | | public: |
381 | | /// @class ColumnData |
382 | | /// Represents raw column data in a PostgreSQL DataRow message |
383 | | class ColumnData |
384 | | { |
385 | | public: |
386 | | /// A constructor that creates ColumnData from raw bytes |
387 | | /// @param[in] data A pointer to the raw column data |
388 | | /// @param[in] dataLen Size of the data in bytes |
389 | 0 | ColumnData(const uint8_t* data, size_t dataLen) : m_Data(data), m_DataLen(dataLen) |
390 | 0 | {} |
391 | | |
392 | | /// @return The raw column data as a vector of bytes |
393 | | std::vector<uint8_t> getData() const |
394 | 0 | { |
395 | 0 | if (!m_Data) |
396 | 0 | { |
397 | 0 | return {}; |
398 | 0 | } |
399 | 0 | return { m_Data, m_Data + m_DataLen }; |
400 | 0 | } |
401 | | |
402 | | /// @return The column data as a hex string |
403 | | std::string toHexString() const; |
404 | | |
405 | | /// @return The column data as a UTF-8 string (empty if conversion fails) |
406 | | std::string toString() const; |
407 | | |
408 | | /// @return True if the column value is NULL |
409 | | bool isNull() const |
410 | 0 | { |
411 | 0 | return m_Data == nullptr; |
412 | 0 | } |
413 | | |
414 | | private: |
415 | | const uint8_t* m_Data; |
416 | | size_t m_DataLen; |
417 | | }; |
418 | | |
419 | | /// A constructor that creates the layer from an existing packet raw data |
420 | | /// @param[in] data A pointer to the raw data |
421 | | /// @param[in] dataLen Size of the data in bytes |
422 | | PostgresDataRowMessage(const uint8_t* data, size_t dataLen) |
423 | 0 | : PostgresMessage(data, dataLen, PostgresMessageType::Backend_DataRow) |
424 | 0 | {} |
425 | | |
426 | | /// @return Vector of column data values |
427 | | std::vector<ColumnData> getDataRow() const; |
428 | | }; |
429 | | |
430 | | /// @class PostgresErrorResponseMessage |
431 | | /// Represents a PostgreSQL ErrorResponse or NoticeResponse message (backend) |
432 | | class PostgresErrorResponseMessage : public PostgresMessage |
433 | | { |
434 | | public: |
435 | | /// @enum ErrorField |
436 | | /// Represents the field types in a PostgreSQL ErrorResponse or NoticeResponse message |
437 | | enum class ErrorField : uint8_t |
438 | | { |
439 | | /// Severity: the field contents are ERROR, FATAL, or PANIC (localized) |
440 | | Severity = 'S', |
441 | | /// Severity: the field contents are ERROR, FATAL, PANIC or DEBUG, LOG, INFO, NOTICE, WARNING, or DEBUG |
442 | | /// (non-localized) |
443 | | SeverityNonLocalized = 'V', |
444 | | /// SQLSTATE code |
445 | | SQLState = 'C', |
446 | | /// Primary human-readable error message |
447 | | Message = 'M', |
448 | | /// Optional secondary error message |
449 | | Detail = 'D', |
450 | | /// Optional hint |
451 | | Hint = 'H', |
452 | | /// Decimal integer indicating an error cursor position |
453 | | Position = 'P', |
454 | | /// Internal cursor position (where error occurred) |
455 | | InternalPosition = 'p', |
456 | | /// Text of internal query |
457 | | InternalQuery = 'q', |
458 | | /// Indicating context of error |
459 | | Where = 'W', |
460 | | /// Schema name |
461 | | Schema = 's', |
462 | | /// Table name |
463 | | Table = 't', |
464 | | /// Column name |
465 | | Column = 'c', |
466 | | /// Data type name |
467 | | DataType = 'd', |
468 | | /// Constraint name |
469 | | Constraint = 'n', |
470 | | /// File name of error |
471 | | File = 'F', |
472 | | /// Line number of error |
473 | | Line = 'L', |
474 | | /// Routine name |
475 | | Routine = 'R', |
476 | | /// Terminator (always '\0') |
477 | | Terminator = '\0' |
478 | | }; |
479 | | |
480 | | /// A map of error field type to value |
481 | | using FieldMap = std::unordered_map<ErrorField, std::string>; |
482 | | |
483 | | /// A constructor that creates the layer from an existing packet raw data |
484 | | /// @param[in] data A pointer to the raw data |
485 | | /// @param[in] dataLen Size of the data in bytes |
486 | | PostgresErrorResponseMessage(const uint8_t* data, size_t dataLen) |
487 | 0 | : PostgresMessage(data, dataLen, PostgresMessageType::Backend_ErrorResponse) |
488 | 0 | {} |
489 | | |
490 | | /// @return The error fields as a map |
491 | | const FieldMap& getFields() const; |
492 | | |
493 | | private: |
494 | | mutable FieldMap m_Fields; |
495 | | mutable bool m_FieldsParsed = false; |
496 | | }; |
497 | | |
498 | | /// @class PostgresLayer |
499 | | /// Represents a PostgreSQL protocol layer |
500 | | class PostgresLayer : public Layer |
501 | | { |
502 | | public: |
503 | | /// A d'tor for this layer |
504 | 67 | ~PostgresLayer() override = default; |
505 | | |
506 | | /// A static method that checks whether the port is considered as PostgreSQL |
507 | | /// @param[in] port The port number to be checked |
508 | | static bool isPostgresPort(uint16_t port) |
509 | 146k | { |
510 | 146k | return port == 5432; |
511 | 146k | } |
512 | | |
513 | | /// Parse a PostgreSQL backend message from raw data |
514 | | /// @param[in] data A pointer to the raw data |
515 | | /// @param[in] dataLen Size of the data in bytes |
516 | | /// @param[in] prevLayer A pointer to the previous layer |
517 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
518 | | /// @return A pointer to the parsed PostgresLayer, or nullptr if parsing fails |
519 | | static PostgresLayer* parsePostgresBackendMessages(uint8_t* data, size_t dataLen, Layer* prevLayer, |
520 | | Packet* packet); |
521 | | |
522 | | /// Parse a PostgreSQL frontend message from raw data |
523 | | /// @param[in] data A pointer to the raw data |
524 | | /// @param[in] dataLen Size of the data in bytes |
525 | | /// @param[in] prevLayer A pointer to the previous layer |
526 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
527 | | /// @return A pointer to the parsed PostgresLayer, or nullptr if parsing fails |
528 | | static PostgresLayer* parsePostgresFrontendMessages(uint8_t* data, size_t dataLen, Layer* prevLayer, |
529 | | Packet* packet); |
530 | | |
531 | | /// @return The message origin (frontend or backend) |
532 | | PostgresMessageOrigin getPostgresOrigin() const |
533 | 0 | { |
534 | 0 | return m_MessageOrigin; |
535 | 0 | } |
536 | | |
537 | | /// @return A vector of all PostgreSQL messages in this layer |
538 | | const PointerVector<PostgresMessage>& getPostgresMessages() const; |
539 | | |
540 | | /// @brief Get a PostgreSQL message by its type |
541 | | /// @param[in] messageType The type of message to retrieve |
542 | | /// @return A pointer to the message, or nullptr if not found |
543 | | const PostgresMessage* getPostgresMessage(const PostgresMessageType& messageType) const; |
544 | | |
545 | | /// @brief Get a PostgreSQL message by its type (template version) |
546 | | /// @tparam TMessage The message type to retrieve (must derive from PostgresMessage) |
547 | | /// @return A pointer to the message of the specified type, or nullptr if not found |
548 | | template <class TMessage, std::enable_if_t<std::is_base_of<PostgresMessage, TMessage>::value, bool> = nullptr> |
549 | | const TMessage* getPostgresMessage() const |
550 | | { |
551 | | const auto& messages = getPostgresMessages(); |
552 | | for (const auto& msg : messages) |
553 | | { |
554 | | auto result = dynamic_cast<const TMessage*>(msg); |
555 | | if (result != nullptr) |
556 | | { |
557 | | return result; |
558 | | } |
559 | | } |
560 | | return nullptr; |
561 | | } |
562 | | |
563 | | // Overridden methods |
564 | | |
565 | | /// @return The size of the Postgres layer header |
566 | | size_t getHeaderLen() const override |
567 | 13 | { |
568 | 13 | return m_DataLen; |
569 | 13 | } |
570 | | |
571 | | /// Does nothing for this layer, Postgres is always last |
572 | | void parseNextLayer() override |
573 | 67 | {} |
574 | | |
575 | | /// Does nothing for this layer |
576 | | void computeCalculateFields() override |
577 | 13 | {} |
578 | | |
579 | | /// @return The OSI layer level of Postgres (Application Layer). |
580 | | OsiModelLayer getOsiModelLayer() const override |
581 | 13 | { |
582 | 13 | return OsiModelApplicationLayer; |
583 | 13 | } |
584 | | |
585 | | /// @return Returns the protocol info as readable string |
586 | | std::string toString() const override; |
587 | | |
588 | | private: |
589 | | PostgresMessageOrigin m_MessageOrigin; |
590 | | mutable PointerVector<PostgresMessage> m_Messages; |
591 | | mutable bool m_MessagesInitialized = false; |
592 | | |
593 | | PostgresLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, |
594 | | PostgresMessageOrigin messageOrigin) |
595 | 67 | : Layer(data, dataLen, prevLayer, packet, Postgres), m_MessageOrigin(messageOrigin) |
596 | 67 | {} |
597 | | }; |
598 | | } // namespace pcpp |