PcapPlusPlus  Next
TcpLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "DeprecationUtils.h"
4 #include "Layer.h"
5 #include "TLVData.h"
6 #include <string.h>
7 
8 #define PCPP_DEPRECATED_TCP_OPTION_TYPE \
9  PCPP_DEPRECATED("enum TcpOptionType is deprecated; Use enum class TcpOptionEnumType instead")
10 
12 
15 namespace pcpp
16 {
19 #pragma pack(push, 1)
20  struct tcphdr
21  {
23  uint16_t portSrc;
25  uint16_t portDst;
27  uint32_t sequenceNumber;
29  uint32_t ackNumber;
30 #if (BYTE_ORDER == LITTLE_ENDIAN)
31  uint16_t reserved : 4;
33  uint16_t dataOffset : 4;
35  uint16_t finFlag : 1;
37  uint16_t synFlag : 1;
39  uint16_t rstFlag : 1;
41  uint16_t pshFlag : 1;
43  uint16_t ackFlag : 1;
45  uint16_t urgFlag : 1;
47  uint16_t eceFlag : 1;
49  uint16_t cwrFlag : 1;
50 #elif (BYTE_ORDER == BIG_ENDIAN)
52  uint16_t dataOffset : 4;
54  uint16_t reserved : 4;
56  uint16_t cwrFlag : 1;
58  uint16_t eceFlag : 1;
60  uint16_t urgFlag : 1;
62  uint16_t ackFlag : 1;
64  uint16_t pshFlag : 1;
66  uint16_t rstFlag : 1;
68  uint16_t synFlag : 1;
70  uint16_t finFlag : 1;
71 #else
72 # error "Endian is not LE nor BE..."
73 #endif
75  uint16_t windowSize;
77  uint16_t headerChecksum;
80  uint16_t urgentPointer;
81  };
82 #pragma pack(pop)
83  static_assert(sizeof(tcphdr) == 20, "tcphdr size is not 20 bytes");
84 
86  enum TcpOptionType : uint8_t
87  {
107  TCPOPT_CC = 11,
115  TCPOPT_MPTCP = 0x1e,
125  TCPOPT_QS = 27,
137  TCPOPT_Unknown = 255
138  };
139 
141  enum class TcpOptionEnumType : uint8_t
142  {
144  Nop = 1,
146  Eol = 0,
148  Mss = 2,
150  Window = 3,
152  SackPerm = 4,
154  Sack = 5,
156  Echo = 6,
158  EchoReply = 7,
160  Timestamp = 8,
162  Cc = 11,
164  CcNew = 12,
166  CcEcho = 13,
168  Md5 = 19,
170  MpTcp = 0x1e,
172  Scps = 20,
174  Snack = 21,
176  RecBound = 22,
178  CorrExp = 23,
180  Qs = 27,
182  UserTo = 28,
184  ExpFd = 0xfd,
186  ExpFe = 0xfe,
188  RvbdProbe = 76,
190  RvbdTrpy = 78,
192  Unknown = 255
193  };
194 
195  // TCP option lengths
196 
198 #define PCPP_TCPOLEN_NOP 1
200 #define PCPP_TCPOLEN_EOL 1
202 #define PCPP_TCPOLEN_MSS 4
204 #define PCPP_TCPOLEN_WINDOW 3
206 #define PCPP_TCPOLEN_SACK_PERM 2
208 #define PCPP_TCPOLEN_SACK_MIN 2
210 #define PCPP_TCPOLEN_ECHO 6
212 #define PCPP_TCPOLEN_ECHOREPLY 6
214 #define PCPP_TCPOLEN_TIMESTAMP 10
216 #define PCPP_TCPOLEN_CC 6
218 #define PCPP_TCPOLEN_CCNEW 6
220 #define PCPP_TCPOLEN_CCECHO 6
222 #define PCPP_TCPOLEN_MD5 18
224 #define PCPP_TCPOLEN_MPTCP_MIN 8
226 #define PCPP_TCPOLEN_SCPS 4
228 #define PCPP_TCPOLEN_SNACK 6
230 #define PCPP_TCPOLEN_RECBOUND 2
232 #define PCPP_TCPOLEN_CORREXP 2
234 #define PCPP_TCPOLEN_QS 8
236 #define PCPP_TCPOLEN_USER_TO 4
238 #define PCPP_TCPOLEN_RVBD_PROBE_MIN 3
240 #define PCPP_TCPOLEN_RVBD_TRPY_MIN 16
242 #define PCPP_TCPOLEN_EXP_MIN 2
243 
247  class TcpOption : public TLVRecord<uint8_t, uint8_t>
248  {
249  public:
252  explicit TcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData)
253  {}
254 
256  ~TcpOption() override = default;
257 
259  PCPP_DEPRECATED("Use getTcpOptionEnumType instead")
261  {
262  return getTcpOptionType(m_Data);
263  }
264 
268  {
269  return getTcpOptionEnumType(m_Data);
270  }
271 
276  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
277  {
278  const auto* data = reinterpret_cast<const TLVRawData*>(recordRawData);
279  if (data == nullptr)
280  return false;
281 
282  if (tlvDataLen < sizeof(TLVRawData::recordType))
283  return false;
284 
285  const auto recordType = getTcpOptionEnumType(data);
286  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
287  return true;
288 
289  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
290  }
291 
292  // implement abstract methods
293 
294  size_t getTotalSize() const override
295  {
296  if (m_Data == nullptr)
297  return 0;
298 
299  const auto recordType = getTcpOptionEnumType(m_Data);
300  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
301  return sizeof(uint8_t);
302 
303  return static_cast<size_t>(m_Data->recordLen);
304  }
305 
306  size_t getDataSize() const override
307  {
308  if (m_Data == nullptr)
309  return 0;
310 
311  const auto recordType = getTcpOptionEnumType(m_Data);
312  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
313  return 0;
314 
315  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
316  }
317 
318  private:
319  static TcpOptionType getTcpOptionType(const TLVRawData* optionRawData)
320  {
321  if (optionRawData == nullptr)
323 
324  return static_cast<TcpOptionType>(optionRawData->recordType);
325  }
326 
327  static TcpOptionEnumType getTcpOptionEnumType(const TLVRawData* optionRawData)
328  {
329  if (optionRawData == nullptr)
331 
332  return static_cast<TcpOptionEnumType>(optionRawData->recordType);
333  }
334  };
335 
340  {
341 
342  public:
344  enum NopEolOptionTypes : uint8_t
345  {
349  EOL
350  };
351 
353  enum class NopEolOptionEnumType : uint8_t
354  {
356  Nop,
358  Eol
359  };
360 
362  PCPP_DEPRECATED_TCP_OPTION_TYPE
363  TcpOptionBuilder(TcpOptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
364  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
365  {}
366 
373  TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
374  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
375  {}
376 
378  PCPP_DEPRECATED_TCP_OPTION_TYPE
379  TcpOptionBuilder(TcpOptionType optionType, uint8_t optionValue)
380  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
381  {}
382 
387  TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue)
388  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
389  {}
390 
392  PCPP_DEPRECATED_TCP_OPTION_TYPE
393  TcpOptionBuilder(TcpOptionType optionType, uint16_t optionValue)
394  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
395  {}
396 
401  TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue)
402  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
403  {}
404 
406  PCPP_DEPRECATED_TCP_OPTION_TYPE
407  TcpOptionBuilder(TcpOptionType optionType, uint32_t optionValue)
408  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
409  {}
410 
415  TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue)
416  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
417  {}
418 
420  PCPP_DEPRECATED("enum NopEolOptionTypes is deprecated; Use enum class NopEolOptionEnumType instead")
421  explicit TcpOptionBuilder(NopEolOptionTypes optionType);
422 
428 
431  TcpOption build() const;
432  };
433 
436  class TcpLayer : public Layer
437  {
438  public:
444  TcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
445 
448 
452  TcpLayer(uint16_t portSrc, uint16_t portDst);
453 
454  ~TcpLayer() override = default;
455 
457  TcpLayer(const TcpLayer& other);
458 
461  TcpLayer& operator=(const TcpLayer& other);
462 
467  {
468  return reinterpret_cast<tcphdr*>(m_Data);
469  }
470 
472  uint16_t getSrcPort() const;
473 
475  uint16_t getDstPort() const;
476 
478  PCPP_DEPRECATED_TCP_OPTION_TYPE
479  TcpOption getTcpOption(TcpOptionType option) const;
480 
486 
490 
497 
499  size_t getTcpOptionCount() const;
500 
506  TcpOption addTcpOption(const TcpOptionBuilder& optionBuilder);
507 
510  PCPP_DEPRECATED("Use insertTcpOptionAfter instead")
511  TcpOption addTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
512  TcpOptionType prevOptionType = TcpOptionType::TCPOPT_Unknown);
513 
523  TcpOption insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
524  TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown);
525 
527  PCPP_DEPRECATED_TCP_OPTION_TYPE
528  bool removeTcpOption(TcpOptionType optionType);
529 
534  bool removeTcpOption(TcpOptionEnumType optionType);
535 
539  bool removeAllTcpOptions();
540 
545  uint16_t calculateChecksum(bool writeResultToPacket);
546 
551  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
552 
553  // implement abstract methods
554 
557  void parseNextLayer() override;
558 
560  size_t getHeaderLen() const override
561  {
562  return getTcpHeader()->dataOffset * 4;
563  }
564 
566  void computeCalculateFields() override;
567 
568  std::string toString() const override;
569 
571  {
572  return OsiModelTransportLayer;
573  }
574 
575  private:
576  TLVRecordReader<TcpOption> m_OptionReader;
577  int m_NumOfTrailingBytes;
578 
579  void initLayer();
580  uint8_t* getOptionsBasePtr() const
581  {
582  return m_Data + sizeof(tcphdr);
583  }
584  TcpOption addTcpOptionAt(const TcpOptionBuilder& optionBuilder, int offset);
585  void adjustTcpOptionTrailer(size_t totalOptSize);
586  void copyLayerData(const TcpLayer& other);
587  };
588 
589  // implementation of inline methods
590 
591  bool TcpLayer::isDataValid(const uint8_t* data, size_t dataLen)
592  {
593  const tcphdr* hdr = reinterpret_cast<const tcphdr*>(data);
594  return dataLen >= sizeof(tcphdr) && hdr->dataOffset >= 5 /* the minimum TCP header size */
595  && dataLen >= hdr->dataOffset * sizeof(uint32_t);
596  }
597 } // namespace pcpp
598 
599 #undef PCPP_DEPRECATED_TCP_OPTION_TYPE
Definition: Layer.h:60
Definition: Packet.h:22
Definition: TLVData.h:357
Definition: TLVData.h:19
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:66
Definition: TLVData.h:204
Definition: TcpLayer.h:437
tcphdr * getTcpHeader() const
Definition: TcpLayer.h:466
OsiModelLayer getOsiModelLayer() const override
Definition: TcpLayer.h:570
uint16_t getSrcPort() const
TcpOption getTcpOption(TcpOptionEnumType option) const
TcpLayer()
A constructor that allocates a new TCP header with zero TCP options.
TcpOption getFirstTcpOption() const
TcpLayer(const TcpLayer &other)
A copy constructor that copy the entire header from the other TcpLayer (including TCP options)
TcpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
uint16_t getDstPort() const
TcpLayer & operator=(const TcpLayer &other)
TcpOption addTcpOption(const TcpOptionBuilder &optionBuilder)
void computeCalculateFields() override
Calculate tcphdr::headerChecksum field.
TcpLayer(uint16_t portSrc, uint16_t portDst)
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: TcpLayer.h:591
size_t getTcpOptionCount() const
std::string toString() const override
TcpOption getNextTcpOption(TcpOption &tcpOption) const
Definition: TcpLayer.h:340
PCPP_DEPRECATED("enum TcpOptionType is deprecated; Use enum class TcpOptionEnumType instead") TcpOptionBuilder(TcpOptionType optionType
NopEolOptionEnumType
An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors.
Definition: TcpLayer.h:354
TcpOptionBuilder(NopEolOptionEnumType optionType)
NopEolOptionTypes
An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors.
Definition: TcpLayer.h:345
@ EOL
EOL TCP option.
Definition: TcpLayer.h:349
@ NOP
NOP TCP option.
Definition: TcpLayer.h:347
TcpOption build() const
Definition: TcpLayer.h:248
TcpOptionEnumType getTcpOptionEnumType() const
Definition: TcpLayer.h:267
TcpOptionType getTcpOptionType() const
Definition: TcpLayer.h:260
size_t getTotalSize() const override
Definition: TcpLayer.h:294
size_t getDataSize() const override
Definition: TcpLayer.h:306
~TcpOption() override=default
A d'tor for this class, currently does nothing.
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TcpLayer.h:276
TcpOption(uint8_t *optionRawData)
Definition: TcpLayer.h:252
The main namespace for the PcapPlusPlus lib.
TcpOptionEnumType
TCP options types.
Definition: TcpLayer.h:142
@ RvbdTrpy
Riverbed transparency option, non IANA registered option number.
@ Eol
End of options.
@ RvbdProbe
Riverbed probe option, non IANA registered option number.
@ CorrExp
SCPS Corruption Experienced.
@ Mss
Segment size negotiating.
@ ExpFd
RFC3692-style Experiment 1 (also improperly used for shipping products)
@ Scps
SCPS Capabilities.
@ Unknown
Unknown option.
@ Md5
MD5 Signature Option.
@ CcEcho
CC.ECHO(obsolete)
@ Timestamp
TCP Timestamps.
@ MpTcp
Multipath TCP.
@ SackPerm
SACK Permitted.
@ Window
Window scaling.
@ CcNew
CC.NEW (obsolete)
@ Echo
Echo (obsoleted by option TcpOptionEnumType::Timestamp)
@ ExpFe
RFC3692-style Experiment 2 (also improperly used for shipping products)
@ UserTo
User Timeout Option (also, other known unauthorized use)
@ EchoReply
Echo Reply (obsoleted by option TcpOptionEnumType::Timestamp)
@ Qs
Quick-Start Response.
@ RecBound
SCPS Record Boundary.
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:225
@ OsiModelTransportLayer
Transport layer (layer 4)
Definition: ProtocolType.h:233
TcpOptionType
TCP options types.
Definition: TcpLayer.h:87
@ TCPOPT_EXP_FD
RFC3692-style Experiment 1 (also improperly used for shipping products)
Definition: TcpLayer.h:129
@ TCPOPT_USER_TO
User Timeout Option (also, other known unauthorized use)
Definition: TcpLayer.h:127
@ TCPOPT_SCPS
SCPS Capabilities.
Definition: TcpLayer.h:117
@ TCPOPT_MSS
Segment size negotiating.
Definition: TcpLayer.h:93
@ PCPP_TCPOPT_NOP
Padding.
Definition: TcpLayer.h:89
@ TCPOPT_QS
Quick-Start Response.
Definition: TcpLayer.h:125
@ PCPP_TCPOPT_WINDOW
Window scaling.
Definition: TcpLayer.h:95
@ TCPOPT_CCNEW
CC.NEW (obsolete)
Definition: TcpLayer.h:109
@ TCPOPT_RVBD_TRPY
Riverbed transparency option, non IANA registered option number.
Definition: TcpLayer.h:135
@ PCPP_TCPOPT_EOL
End of options.
Definition: TcpLayer.h:91
@ TCPOPT_Unknown
Unknown option.
Definition: TcpLayer.h:137
@ TCPOPT_MPTCP
Multipath TCP.
Definition: TcpLayer.h:115
@ TCPOPT_EXP_FE
RFC3692-style Experiment 2 (also improperly used for shipping products)
Definition: TcpLayer.h:131
@ TCPOPT_CC
CC (obsolete)
Definition: TcpLayer.h:107
@ TCPOPT_ECHOREPLY
Echo Reply (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:103
@ TCPOPT_RVBD_PROBE
Riverbed probe option, non IANA registered option number.
Definition: TcpLayer.h:133
@ TCPOPT_MD5
MD5 Signature Option.
Definition: TcpLayer.h:113
@ TCPOPT_SNACK
SCPS SNACK.
Definition: TcpLayer.h:119
@ PCPP_TCPOPT_TIMESTAMP
TCP Timestamps.
Definition: TcpLayer.h:105
@ TCPOPT_CORREXP
SCPS Corruption Experienced.
Definition: TcpLayer.h:123
@ TCPOPT_RECBOUND
SCPS Record Boundary.
Definition: TcpLayer.h:121
@ TCPOPT_SACK_PERM
SACK Permitted.
Definition: TcpLayer.h:97
@ TCPOPT_CCECHO
CC.ECHO(obsolete)
Definition: TcpLayer.h:111
@ PCPP_TCPOPT_SACK
SACK Block.
Definition: TcpLayer.h:99
@ TCPOPT_ECHO
Echo (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:101
Definition: TcpLayer.h:21
uint16_t pshFlag
PSH flag.
Definition: TcpLayer.h:41
uint16_t cwrFlag
CWR flag.
Definition: TcpLayer.h:49
uint16_t urgFlag
URG flag.
Definition: TcpLayer.h:45
uint32_t sequenceNumber
Sequence number.
Definition: TcpLayer.h:27
uint16_t rstFlag
RST flag.
Definition: TcpLayer.h:39
uint16_t urgentPointer
Definition: TcpLayer.h:80
uint16_t synFlag
SYN flag.
Definition: TcpLayer.h:37
uint16_t portDst
Destination TCP port.
Definition: TcpLayer.h:25
uint16_t portSrc
Source TCP port.
Definition: TcpLayer.h:23
uint16_t dataOffset
Specifies the size of the TCP header in 32-bit words.
Definition: TcpLayer.h:33
uint16_t eceFlag
ECE flag.
Definition: TcpLayer.h:47
uint16_t windowSize
The size of the receive window, which specifies the number of window size units (by default,...
Definition: TcpLayer.h:75
uint16_t finFlag
FIN flag.
Definition: TcpLayer.h:35
uint16_t ackFlag
ACK flag.
Definition: TcpLayer.h:43
uint32_t ackNumber
Acknowledgment number.
Definition: TcpLayer.h:29
uint16_t headerChecksum
The 16-bit checksum field is used for error-checking of the header and data.
Definition: TcpLayer.h:77