PcapPlusPlus  Next
PostgresLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "PointerVector.h"
5 #include <memory>
6 #include <ostream>
7 #include <unordered_map>
8 
10 
13 namespace pcpp
14 {
15 
19  {
20  Frontend,
21  Backend
22  };
23 
27  {
28  public:
30  enum Value : uint8_t
31  {
32  // Frontend (client) message types
33 
70 
71  // Backend (server) message types
72 
143  };
144 
145  constexpr PostgresMessageType() : m_Value(Frontend_Unknown)
146  {}
147 
148  // cppcheck-suppress noExplicitConstructor
151  constexpr PostgresMessageType(Value value) : m_Value(value)
152  {}
153 
156  char toChar() const;
157 
160  std::string toString() const;
161 
166  friend std::ostream& operator<<(std::ostream& os, const PostgresMessageType& messageType)
167  {
168  os << messageType.toString();
169  return os;
170  }
171 
174  explicit operator std::string() const
175  {
176  return toString();
177  }
178 
182 
183  // Allow switch and comparisons
184  constexpr operator Value() const
185  {
186  return m_Value;
187  }
188 
189  // Prevent usage: if(PostgresMessageType)
190  explicit operator bool() const = delete;
191 
192  private:
193  Value m_Value;
194  };
195 
199  {
200  public:
201  virtual ~PostgresMessage() = default;
202 
207  static std::unique_ptr<PostgresMessage> parsePostgresBackendMessage(const uint8_t* data, size_t dataLen);
208 
213  static std::unique_ptr<PostgresMessage> parsePostgresFrontendMessage(const uint8_t* data, size_t dataLen);
214 
217  {
218  return m_MessageType;
219  }
220 
223  {
224  return m_MessageType.getOrigin();
225  }
226 
229  uint32_t getMessageLength() const;
230 
233  size_t getTotalMessageLength() const
234  {
235  return m_DataLen;
236  }
237 
240  std::vector<uint8_t> getRawPayload() const;
241 
242  protected:
243  PostgresMessage(const uint8_t* data, size_t dataLen, const PostgresMessageType& messageType)
244  : m_Data(data), m_DataLen(dataLen), m_MessageType(messageType)
245  {}
246 
247  const uint8_t* m_Data;
248  size_t m_DataLen;
249  PostgresMessageType m_MessageType;
250  };
251 
255  {
256  public:
258  using ParameterMap = std::unordered_map<std::string, std::string>;
259 
263  PostgresStartupMessage(const uint8_t* data, size_t dataLen)
264  : PostgresMessage(data, dataLen, PostgresMessageType::Frontend_StartupMessage)
265  {}
266 
268  uint32_t getProtocolVersion() const;
269 
271  uint16_t getProtocolMajorVersion() const;
272 
274  uint16_t getProtocolMinorVersion() const;
275 
277  const ParameterMap& getParameters() const;
278 
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 
295  {
296  public:
300  PostgresParameterStatus(const uint8_t* data, size_t dataLen)
301  : PostgresMessage(data, dataLen, PostgresMessageType::Backend_ParameterStatus)
302  {}
303 
305  std::string getParameterName() const;
306 
308  std::string getParameterValue() const;
309  };
310 
314  {
315  public:
319  PostgresQueryMessage(const uint8_t* data, size_t dataLen)
320  : PostgresMessage(data, dataLen, PostgresMessageType::Frontend_Query)
321  {}
322 
324  std::string getQuery() const;
325  };
326 
330  {
331  public:
336  {
338  Text = 0,
340  Binary = 1,
342  Unknown = 2
343  };
344 
348  {
350  std::string name;
352  uint32_t tableOID;
354  uint16_t columnIndex;
356  uint32_t typeOID;
358  int16_t typeSize;
360  int32_t typeModifier;
363  };
364 
368  PostgresRowDescriptionMessage(const uint8_t* data, size_t dataLen)
369  : PostgresMessage(data, dataLen, PostgresMessageType::Backend_RowDescription)
370  {}
371 
373  std::vector<PostgresColumnInfo> getColumnInfos() const;
374  };
375 
379  {
380  public:
384  {
385  public:
389  ColumnData(const uint8_t* data, size_t dataLen) : m_Data(data), m_DataLen(dataLen)
390  {}
391 
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 
403  std::string toHexString() const;
404 
406  std::string toString() const;
407 
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 
422  PostgresDataRowMessage(const uint8_t* data, size_t dataLen)
423  : PostgresMessage(data, dataLen, PostgresMessageType::Backend_DataRow)
424  {}
425 
427  std::vector<ColumnData> getDataRow() const;
428  };
429 
433  {
434  public:
437  enum class ErrorField : uint8_t
438  {
440  Severity = 'S',
443  SeverityNonLocalized = 'V',
445  SQLState = 'C',
447  Message = 'M',
449  Detail = 'D',
451  Hint = 'H',
453  Position = 'P',
455  InternalPosition = 'p',
457  InternalQuery = 'q',
459  Where = 'W',
461  Schema = 's',
463  Table = 't',
465  Column = 'c',
467  DataType = 'd',
469  Constraint = 'n',
471  File = 'F',
473  Line = 'L',
475  Routine = 'R',
477  Terminator = '\0'
478  };
479 
481  using FieldMap = std::unordered_map<ErrorField, std::string>;
482 
486  PostgresErrorResponseMessage(const uint8_t* data, size_t dataLen)
487  : PostgresMessage(data, dataLen, PostgresMessageType::Backend_ErrorResponse)
488  {}
489 
491  const FieldMap& getFields() const;
492 
493  private:
494  mutable FieldMap m_Fields;
495  mutable bool m_FieldsParsed = false;
496  };
497 
500  class PostgresLayer : public Layer
501  {
502  public:
504  ~PostgresLayer() override = default;
505 
508  static bool isPostgresPort(uint16_t port)
509  {
510  return port == 5432;
511  }
512 
519  static PostgresLayer* parsePostgresBackendMessages(uint8_t* data, size_t dataLen, Layer* prevLayer,
520  Packet* packet);
521 
528  static PostgresLayer* parsePostgresFrontendMessages(uint8_t* data, size_t dataLen, Layer* prevLayer,
529  Packet* packet);
530 
533  {
534  return m_MessageOrigin;
535  }
536 
539 
543  const PostgresMessage* getPostgresMessage(const PostgresMessageType& messageType) const;
544 
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 
566  size_t getHeaderLen() const override
567  {
568  return m_DataLen;
569  }
570 
572  void parseNextLayer() override
573  {}
574 
576  void computeCalculateFields() override
577  {}
578 
581  {
583  }
584 
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  : Layer(data, dataLen, prevLayer, packet, Postgres), m_MessageOrigin(messageOrigin)
596  {}
597  };
598 } // namespace pcpp
Definition: Layer.h:115
Definition: Packet.h:48
Definition: PointerVector.h:50
Definition: PostgresLayer.h:384
ColumnData(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:389
std::vector< uint8_t > getData() const
Definition: PostgresLayer.h:393
bool isNull() const
Definition: PostgresLayer.h:409
Definition: PostgresLayer.h:379
PostgresDataRowMessage(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:422
std::vector< ColumnData > getDataRow() const
Definition: PostgresLayer.h:433
ErrorField
Definition: PostgresLayer.h:438
@ Severity
Severity: the field contents are ERROR, FATAL, or PANIC (localized)
@ Message
Primary human-readable error message.
@ InternalPosition
Internal cursor position (where error occurred)
@ Position
Decimal integer indicating an error cursor position.
@ Detail
Optional secondary error message.
PostgresErrorResponseMessage(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:486
std::unordered_map< ErrorField, std::string > FieldMap
A map of error field type to value.
Definition: PostgresLayer.h:481
const FieldMap & getFields() const
Definition: PostgresLayer.h:501
static PostgresLayer * parsePostgresFrontendMessages(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
void computeCalculateFields() override
Does nothing for this layer.
Definition: PostgresLayer.h:576
~PostgresLayer() override=default
A d'tor for this layer.
const PostgresMessage * getPostgresMessage(const PostgresMessageType &messageType) const
Get a PostgreSQL message by its type.
PostgresMessageOrigin getPostgresOrigin() const
Definition: PostgresLayer.h:532
void parseNextLayer() override
Does nothing for this layer, Postgres is always last.
Definition: PostgresLayer.h:572
size_t getHeaderLen() const override
Definition: PostgresLayer.h:566
OsiModelLayer getOsiModelLayer() const override
Definition: PostgresLayer.h:580
static PostgresLayer * parsePostgresBackendMessages(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
static bool isPostgresPort(uint16_t port)
Definition: PostgresLayer.h:508
const PointerVector< PostgresMessage > & getPostgresMessages() const
const TMessage * getPostgresMessage() const
Get a PostgreSQL message by its type (template version)
Definition: PostgresLayer.h:549
std::string toString() const override
Definition: PostgresLayer.h:199
static std::unique_ptr< PostgresMessage > parsePostgresFrontendMessage(const uint8_t *data, size_t dataLen)
Parse a PostgreSQL frontend message from raw data.
PostgresMessageType getMessageType() const
Definition: PostgresLayer.h:216
PostgresMessageOrigin getMessageOrigin() const
Definition: PostgresLayer.h:222
std::vector< uint8_t > getRawPayload() const
Returns the raw payload bytes of the message.
uint32_t getMessageLength() const
Returns the length of the message payload.
size_t getTotalMessageLength() const
Returns the total length of the message including the length field.
Definition: PostgresLayer.h:233
static std::unique_ptr< PostgresMessage > parsePostgresBackendMessage(const uint8_t *data, size_t dataLen)
Parse a PostgreSQL backend message from raw data.
Definition: PostgresLayer.h:27
constexpr PostgresMessageType(Value value)
Constructs a PostgresMessageType object from a Value enum.
Definition: PostgresLayer.h:151
friend std::ostream & operator<<(std::ostream &os, const PostgresMessageType &messageType)
Stream operator for PostgresMessageType.
Definition: PostgresLayer.h:166
std::string toString() const
Returns a string representation of the message type.
char toChar() const
Converts the message type to its character representation.
Value
Define enum types for all PostgreSQL message types.
Definition: PostgresLayer.h:31
@ Backend_NoticeResponse
Notice response (warning)
Definition: PostgresLayer.h:126
@ Backend_PortalSuspended
Portal suspended (during cursor fetch)
Definition: PostgresLayer.h:136
@ Backend_CopyBothResponse
Copy both response (during COPY bidirectional)
Definition: PostgresLayer.h:112
@ Backend_ParseComplete
Parse complete.
Definition: PostgresLayer.h:134
@ Backend_CopyDone
Copy done (during COPY)
Definition: PostgresLayer.h:106
@ Backend_EmptyQueryResponse
Empty query response.
Definition: PostgresLayer.h:116
@ Backend_ErrorResponse
Error response.
Definition: PostgresLayer.h:118
@ Backend_NoData
No data (for queries that don't return rows)
Definition: PostgresLayer.h:124
@ Backend_AuthenticationKerberosV5
Authentication using Kerberos V5.
Definition: PostgresLayer.h:78
@ Backend_AuthenticationGSSContinue
GSSAPI authentication continues.
Definition: PostgresLayer.h:86
@ Frontend_FunctionCall
Function call message.
Definition: PostgresLayer.h:55
@ Backend_AuthenticationKerberosV4
Authentication using Kerberos V4.
Definition: PostgresLayer.h:76
@ Backend_AuthenticationCleartextPassword
Authentication using cleartext password.
Definition: PostgresLayer.h:80
@ Frontend_Parse
Parse message (prepared statement)
Definition: PostgresLayer.h:45
@ Backend_BindComplete
Bind complete.
Definition: PostgresLayer.h:98
@ Backend_FunctionCallResponse
Function call response.
Definition: PostgresLayer.h:120
@ Frontend_CopyDone
Copy done message (during COPY)
Definition: PostgresLayer.h:63
@ Backend_NegotiateProtocolVersion
Negotiate protocol version.
Definition: PostgresLayer.h:122
@ Frontend_Terminate
Terminate message (disconnect)
Definition: PostgresLayer.h:67
@ Backend_AuthenticationSASLFinal
SASL authentication final message.
Definition: PostgresLayer.h:94
@ Frontend_CopyData
Copy data message (during COPY)
Definition: PostgresLayer.h:61
@ Backend_AuthenticationMD5Password
Authentication using MD5 password.
Definition: PostgresLayer.h:82
@ Backend_AuthenticationOk
Authentication successful.
Definition: PostgresLayer.h:74
@ Backend_ParameterDescription
Parameter description (for prepared statements)
Definition: PostgresLayer.h:130
@ Backend_CopyOutResponse
Copy out response (during COPY to client)
Definition: PostgresLayer.h:110
@ Backend_CommandComplete
Command complete (after query execution)
Definition: PostgresLayer.h:102
@ Frontend_CopyFail
Copy fail message (during COPY)
Definition: PostgresLayer.h:65
@ Backend_CopyData
Copy data (during COPY)
Definition: PostgresLayer.h:104
@ Frontend_Sync
Sync message (sync after batch)
Definition: PostgresLayer.h:59
@ Frontend_GSSENCRequest
GSSAPI encryption request.
Definition: PostgresLayer.h:41
@ Frontend_StartupMessage
Startup message (first message in connection)
Definition: PostgresLayer.h:35
@ Backend_DataRow
Data row (result set)
Definition: PostgresLayer.h:114
@ Backend_AuthenticationGSS
Authentication using GSSAPI.
Definition: PostgresLayer.h:84
@ Backend_AuthenticationSASL
SASL authentication mechanism list.
Definition: PostgresLayer.h:90
@ Frontend_SSLRequest
SSL request code (sent by client to request SSL)
Definition: PostgresLayer.h:37
@ Backend_BackendKeyData
Backend key data (secret key for cancel)
Definition: PostgresLayer.h:96
@ Backend_CloseComplete
Close complete.
Definition: PostgresLayer.h:100
@ Backend_AuthenticationSSPI
Authentication using SSPI.
Definition: PostgresLayer.h:88
@ Backend_CopyInResponse
Copy in response (during COPY from client)
Definition: PostgresLayer.h:108
@ Backend_Unknown
Unknown backend message type.
Definition: PostgresLayer.h:142
@ Frontend_Execute
Execute message (portal execution)
Definition: PostgresLayer.h:49
@ Backend_AuthenticationSASLContinue
SASL authentication continues.
Definition: PostgresLayer.h:92
@ Backend_ReadyForQuery
Ready for query (idle state)
Definition: PostgresLayer.h:138
@ Backend_ParameterStatus
Parameter status (runtime parameter setting)
Definition: PostgresLayer.h:132
@ Frontend_Describe
Describe message (describe a prepared statement or portal)
Definition: PostgresLayer.h:53
@ Frontend_Close
Close message (close a prepared statement or portal)
Definition: PostgresLayer.h:51
@ Frontend_Query
Simple query message.
Definition: PostgresLayer.h:43
@ Frontend_Bind
Bind message (portal binding)
Definition: PostgresLayer.h:47
@ Backend_NotificationResponse
Notification response (LISTEN/NOTIFY)
Definition: PostgresLayer.h:128
@ Frontend_CancelRequest
Cancel request (sent by client to cancel a running query)
Definition: PostgresLayer.h:39
@ Frontend_Unknown
Unknown frontend message type.
Definition: PostgresLayer.h:69
@ Backend_RowDescription
Row description (column definitions)
Definition: PostgresLayer.h:140
@ Frontend_Flush
Flush message.
Definition: PostgresLayer.h:57
PostgresMessageOrigin getOrigin() const
Returns the origin of the message (frontend or backend)
Definition: PostgresLayer.h:295
std::string getParameterValue() const
PostgresParameterStatus(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:300
std::string getParameterName() const
Definition: PostgresLayer.h:314
std::string getQuery() const
PostgresQueryMessage(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:319
Definition: PostgresLayer.h:330
PostgresRowDescriptionMessage(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:368
std::vector< PostgresColumnInfo > getColumnInfos() const
PostgresColumnFormat
Definition: PostgresLayer.h:336
Definition: PostgresLayer.h:255
std::string getParameter(const std::string &name) const
PostgresStartupMessage(const uint8_t *data, size_t dataLen)
Definition: PostgresLayer.h:263
uint32_t getProtocolVersion() const
std::unordered_map< std::string, std::string > ParameterMap
A map of parameter name to value.
Definition: PostgresLayer.h:258
uint16_t getProtocolMajorVersion() const
const ParameterMap & getParameters() const
uint16_t getProtocolMinorVersion() const
const ProtocolType Postgres
PostgreSQL protocol.
Definition: ProtocolType.h:255
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
PostgresMessageOrigin
Definition: PostgresLayer.h:19
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:264
@ OsiModelApplicationLayer
Application layer (layer 7)
Definition: ProtocolType.h:278
int16_t typeSize
Type size (-1 for variable length)
Definition: PostgresLayer.h:358
std::string name
Column name.
Definition: PostgresLayer.h:350
uint16_t columnIndex
Column index within the table.
Definition: PostgresLayer.h:354
PostgresColumnFormat format
Format.
Definition: PostgresLayer.h:362
uint32_t typeOID
Data type OID.
Definition: PostgresLayer.h:356
int32_t typeModifier
Type modifier (-1 if none)
Definition: PostgresLayer.h:360
uint32_t tableOID
Table OID (0 if not from a table column)
Definition: PostgresLayer.h:352