@@ -308,6 +308,193 @@ namespace pcpp
308308 std::string getParameterValue () const ;
309309 };
310310
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+ : PostgresMessage(data, dataLen, PostgresMessageType::Frontend_Query)
321+ {}
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+ : PostgresMessage(data, dataLen, PostgresMessageType::Backend_RowDescription)
370+ {}
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+ ColumnData (const uint8_t * data, size_t dataLen) : m_Data(data), m_DataLen(dataLen)
390+ {}
391+
392+ // / @return The raw column data as a vector of bytes
393+ std::vector<uint8_t > getData () const
394+ {
395+ if (!m_Data)
396+ {
397+ return {};
398+ }
399+ return { m_Data, m_Data + m_DataLen };
400+ }
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+ {
411+ return m_Data == nullptr ;
412+ }
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+ : PostgresMessage(data, dataLen, PostgresMessageType::Backend_DataRow)
424+ {}
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+ : PostgresMessage(data, dataLen, PostgresMessageType::Backend_ErrorResponse)
488+ {}
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+
311498 // / @class PostgresLayer
312499 // / Represents a PostgreSQL protocol layer
313500 class PostgresLayer : public Layer
0 commit comments