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)
32  uint16_t accurateEcnFlag : 1;
34  uint16_t reserved : 3;
36  uint16_t dataOffset : 4;
38  uint16_t finFlag : 1;
40  uint16_t synFlag : 1;
42  uint16_t rstFlag : 1;
44  uint16_t pshFlag : 1;
46  uint16_t ackFlag : 1;
48  uint16_t urgFlag : 1;
50  uint16_t eceFlag : 1;
52  uint16_t cwrFlag : 1;
53 #elif (BYTE_ORDER == BIG_ENDIAN)
55  uint16_t dataOffset : 4;
57  uint16_t reserved : 3;
59  uint16_t accurateEcnFlag : 1;
61  uint16_t cwrFlag : 1;
63  uint16_t eceFlag : 1;
65  uint16_t urgFlag : 1;
67  uint16_t ackFlag : 1;
69  uint16_t pshFlag : 1;
71  uint16_t rstFlag : 1;
73  uint16_t synFlag : 1;
75  uint16_t finFlag : 1;
76 #else
77 # error "Endian is not LE nor BE..."
78 #endif
80  uint16_t windowSize;
82  uint16_t headerChecksum;
85  uint16_t urgentPointer;
86  };
87 #pragma pack(pop)
88  static_assert(sizeof(tcphdr) == 20, "tcphdr size is not 20 bytes");
89 
91  enum TcpOptionType : uint8_t
92  {
112  TCPOPT_CC = 11,
120  TCPOPT_MPTCP = 0x1e,
130  TCPOPT_QS = 27,
142  TCPOPT_Unknown = 255
143  };
144 
146  enum class TcpOptionEnumType : uint8_t
147  {
149  Nop = 1,
151  Eol = 0,
153  Mss = 2,
155  Window = 3,
157  SackPerm = 4,
159  Sack = 5,
161  Echo = 6,
163  EchoReply = 7,
165  Timestamp = 8,
167  Cc = 11,
169  CcNew = 12,
171  CcEcho = 13,
173  Md5 = 19,
175  MpTcp = 0x1e,
177  Scps = 20,
179  Snack = 21,
181  RecBound = 22,
183  CorrExp = 23,
185  Qs = 27,
187  UserTo = 28,
189  ExpFd = 0xfd,
191  ExpFe = 0xfe,
193  RvbdProbe = 76,
195  RvbdTrpy = 78,
197  Unknown = 255
198  };
199 
200  // TCP option lengths
201 
203 #define PCPP_TCPOLEN_NOP 1
205 #define PCPP_TCPOLEN_EOL 1
207 #define PCPP_TCPOLEN_MSS 4
209 #define PCPP_TCPOLEN_WINDOW 3
211 #define PCPP_TCPOLEN_SACK_PERM 2
213 #define PCPP_TCPOLEN_SACK_MIN 2
215 #define PCPP_TCPOLEN_ECHO 6
217 #define PCPP_TCPOLEN_ECHOREPLY 6
219 #define PCPP_TCPOLEN_TIMESTAMP 10
221 #define PCPP_TCPOLEN_CC 6
223 #define PCPP_TCPOLEN_CCNEW 6
225 #define PCPP_TCPOLEN_CCECHO 6
227 #define PCPP_TCPOLEN_MD5 18
229 #define PCPP_TCPOLEN_MPTCP_MIN 8
231 #define PCPP_TCPOLEN_SCPS 4
233 #define PCPP_TCPOLEN_SNACK 6
235 #define PCPP_TCPOLEN_RECBOUND 2
237 #define PCPP_TCPOLEN_CORREXP 2
239 #define PCPP_TCPOLEN_QS 8
241 #define PCPP_TCPOLEN_USER_TO 4
243 #define PCPP_TCPOLEN_RVBD_PROBE_MIN 3
245 #define PCPP_TCPOLEN_RVBD_TRPY_MIN 16
247 #define PCPP_TCPOLEN_EXP_MIN 2
248 
252  class TcpOption : public TLVRecord<uint8_t, uint8_t>
253  {
254  public:
257  explicit TcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData)
258  {}
259 
261  ~TcpOption() override = default;
262 
264  PCPP_DEPRECATED("Use getTcpOptionEnumType instead")
266  {
267  return getTcpOptionType(m_Data);
268  }
269 
273  {
274  return getTcpOptionEnumType(m_Data);
275  }
276 
281  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
282  {
283  const auto* data = reinterpret_cast<const TLVRawData*>(recordRawData);
284  if (data == nullptr)
285  return false;
286 
287  if (tlvDataLen < sizeof(TLVRawData::recordType))
288  return false;
289 
290  const auto recordType = getTcpOptionEnumType(data);
291  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
292  return true;
293 
294  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
295  }
296 
297  // implement abstract methods
298 
299  size_t getTotalSize() const override
300  {
301  if (m_Data == nullptr)
302  return 0;
303 
304  const auto recordType = getTcpOptionEnumType(m_Data);
305  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
306  return sizeof(uint8_t);
307 
308  return static_cast<size_t>(m_Data->recordLen);
309  }
310 
311  size_t getDataSize() const override
312  {
313  if (m_Data == nullptr)
314  return 0;
315 
316  const auto recordType = getTcpOptionEnumType(m_Data);
317  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
318  return 0;
319 
320  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
321  }
322 
323  private:
324  static TcpOptionType getTcpOptionType(const TLVRawData* optionRawData)
325  {
326  if (optionRawData == nullptr)
328 
329  return static_cast<TcpOptionType>(optionRawData->recordType);
330  }
331 
332  static TcpOptionEnumType getTcpOptionEnumType(const TLVRawData* optionRawData)
333  {
334  if (optionRawData == nullptr)
336 
337  return static_cast<TcpOptionEnumType>(optionRawData->recordType);
338  }
339  };
340 
345  {
346 
347  public:
349  enum NopEolOptionTypes : uint8_t
350  {
354  EOL
355  };
356 
358  enum class NopEolOptionEnumType : uint8_t
359  {
361  Nop,
363  Eol
364  };
365 
367  PCPP_DEPRECATED_TCP_OPTION_TYPE
368  TcpOptionBuilder(TcpOptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
369  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
370  {}
371 
378  TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
379  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
380  {}
381 
383  PCPP_DEPRECATED_TCP_OPTION_TYPE
384  TcpOptionBuilder(TcpOptionType optionType, uint8_t optionValue)
385  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
386  {}
387 
392  TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue)
393  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
394  {}
395 
397  PCPP_DEPRECATED_TCP_OPTION_TYPE
398  TcpOptionBuilder(TcpOptionType optionType, uint16_t optionValue)
399  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
400  {}
401 
406  TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue)
407  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
408  {}
409 
411  PCPP_DEPRECATED_TCP_OPTION_TYPE
412  TcpOptionBuilder(TcpOptionType optionType, uint32_t optionValue)
413  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
414  {}
415 
420  TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue)
421  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
422  {}
423 
425  PCPP_DEPRECATED("enum NopEolOptionTypes is deprecated; Use enum class NopEolOptionEnumType instead")
426  explicit TcpOptionBuilder(NopEolOptionTypes optionType);
427 
433 
436  TcpOption build() const;
437  };
438 
441  class TcpLayer : public Layer
442  {
443  public:
449  TcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
450 
453 
457  TcpLayer(uint16_t portSrc, uint16_t portDst);
458 
459  ~TcpLayer() override = default;
460 
462  TcpLayer(const TcpLayer& other);
463 
466  TcpLayer& operator=(const TcpLayer& other);
467 
472  {
473  return reinterpret_cast<tcphdr*>(m_Data);
474  }
475 
477  uint16_t getSrcPort() const;
478 
480  uint16_t getDstPort() const;
481 
483  PCPP_DEPRECATED_TCP_OPTION_TYPE
484  TcpOption getTcpOption(TcpOptionType option) const;
485 
491 
495 
502 
504  size_t getTcpOptionCount() const;
505 
511  TcpOption addTcpOption(const TcpOptionBuilder& optionBuilder);
512 
515  PCPP_DEPRECATED("Use insertTcpOptionAfter instead")
516  TcpOption addTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
517  TcpOptionType prevOptionType = TcpOptionType::TCPOPT_Unknown);
518 
528  TcpOption insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
529  TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown);
530 
532  PCPP_DEPRECATED_TCP_OPTION_TYPE
533  bool removeTcpOption(TcpOptionType optionType);
534 
539  bool removeTcpOption(TcpOptionEnumType optionType);
540 
544  bool removeAllTcpOptions();
545 
550  uint16_t calculateChecksum(bool writeResultToPacket);
551 
556  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
557 
558  // implement abstract methods
559 
562  void parseNextLayer() override;
563 
565  size_t getHeaderLen() const override
566  {
567  return getTcpHeader()->dataOffset * 4;
568  }
569 
571  void computeCalculateFields() override;
572 
573  std::string toString() const override;
574 
576  {
577  return OsiModelTransportLayer;
578  }
579 
580  private:
581  TLVRecordReader<TcpOption> m_OptionReader;
582  int m_NumOfTrailingBytes;
583 
584  void initLayer();
585  uint8_t* getOptionsBasePtr() const
586  {
587  return m_Data + sizeof(tcphdr);
588  }
589  TcpOption addTcpOptionAt(const TcpOptionBuilder& optionBuilder, int offset);
590  void adjustTcpOptionTrailer(size_t totalOptSize);
591  void copyLayerData(const TcpLayer& other);
592  };
593 
594  // implementation of inline methods
595 
596  bool TcpLayer::isDataValid(const uint8_t* data, size_t dataLen)
597  {
598  const tcphdr* hdr = reinterpret_cast<const tcphdr*>(data);
599  return dataLen >= sizeof(tcphdr) && hdr->dataOffset >= 5 /* the minimum TCP header size */
600  && dataLen >= hdr->dataOffset * sizeof(uint32_t);
601  }
602 } // namespace pcpp
603 
604 #undef PCPP_DEPRECATED_TCP_OPTION_TYPE
Definition: Layer.h:62
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:442
tcphdr * getTcpHeader() const
Definition: TcpLayer.h:471
OsiModelLayer getOsiModelLayer() const override
Definition: TcpLayer.h:575
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:596
size_t getTcpOptionCount() const
std::string toString() const override
TcpOption getNextTcpOption(TcpOption &tcpOption) const
Definition: TcpLayer.h:345
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:359
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:350
@ EOL
EOL TCP option.
Definition: TcpLayer.h:354
@ NOP
NOP TCP option.
Definition: TcpLayer.h:352
TcpOption build() const
Definition: TcpLayer.h:253
TcpOptionEnumType getTcpOptionEnumType() const
Definition: TcpLayer.h:272
TcpOptionType getTcpOptionType() const
Definition: TcpLayer.h:265
size_t getTotalSize() const override
Definition: TcpLayer.h:299
size_t getDataSize() const override
Definition: TcpLayer.h:311
~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:281
TcpOption(uint8_t *optionRawData)
Definition: TcpLayer.h:257
The main namespace for the PcapPlusPlus lib.
TcpOptionEnumType
TCP options types.
Definition: TcpLayer.h:147
@ 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:228
@ OsiModelTransportLayer
Transport layer (layer 4)
Definition: ProtocolType.h:236
TcpOptionType
TCP options types.
Definition: TcpLayer.h:92
@ TCPOPT_EXP_FD
RFC3692-style Experiment 1 (also improperly used for shipping products)
Definition: TcpLayer.h:134
@ TCPOPT_USER_TO
User Timeout Option (also, other known unauthorized use)
Definition: TcpLayer.h:132
@ TCPOPT_SCPS
SCPS Capabilities.
Definition: TcpLayer.h:122
@ TCPOPT_MSS
Segment size negotiating.
Definition: TcpLayer.h:98
@ PCPP_TCPOPT_NOP
Padding.
Definition: TcpLayer.h:94
@ TCPOPT_QS
Quick-Start Response.
Definition: TcpLayer.h:130
@ PCPP_TCPOPT_WINDOW
Window scaling.
Definition: TcpLayer.h:100
@ TCPOPT_CCNEW
CC.NEW (obsolete)
Definition: TcpLayer.h:114
@ TCPOPT_RVBD_TRPY
Riverbed transparency option, non IANA registered option number.
Definition: TcpLayer.h:140
@ PCPP_TCPOPT_EOL
End of options.
Definition: TcpLayer.h:96
@ TCPOPT_Unknown
Unknown option.
Definition: TcpLayer.h:142
@ TCPOPT_MPTCP
Multipath TCP.
Definition: TcpLayer.h:120
@ TCPOPT_EXP_FE
RFC3692-style Experiment 2 (also improperly used for shipping products)
Definition: TcpLayer.h:136
@ TCPOPT_CC
CC (obsolete)
Definition: TcpLayer.h:112
@ TCPOPT_ECHOREPLY
Echo Reply (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:108
@ TCPOPT_RVBD_PROBE
Riverbed probe option, non IANA registered option number.
Definition: TcpLayer.h:138
@ TCPOPT_MD5
MD5 Signature Option.
Definition: TcpLayer.h:118
@ TCPOPT_SNACK
SCPS SNACK.
Definition: TcpLayer.h:124
@ PCPP_TCPOPT_TIMESTAMP
TCP Timestamps.
Definition: TcpLayer.h:110
@ TCPOPT_CORREXP
SCPS Corruption Experienced.
Definition: TcpLayer.h:128
@ TCPOPT_RECBOUND
SCPS Record Boundary.
Definition: TcpLayer.h:126
@ TCPOPT_SACK_PERM
SACK Permitted.
Definition: TcpLayer.h:102
@ TCPOPT_CCECHO
CC.ECHO(obsolete)
Definition: TcpLayer.h:116
@ PCPP_TCPOPT_SACK
SACK Block.
Definition: TcpLayer.h:104
@ TCPOPT_ECHO
Echo (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:106
Definition: TcpLayer.h:21
uint16_t pshFlag
PSH flag.
Definition: TcpLayer.h:44
uint16_t cwrFlag
CWR flag.
Definition: TcpLayer.h:52
uint16_t urgFlag
URG flag.
Definition: TcpLayer.h:48
uint32_t sequenceNumber
Sequence number.
Definition: TcpLayer.h:27
uint16_t accurateEcnFlag
Accurate ECN flag.
Definition: TcpLayer.h:32
uint16_t rstFlag
RST flag.
Definition: TcpLayer.h:42
uint16_t urgentPointer
Definition: TcpLayer.h:85
uint16_t synFlag
SYN flag.
Definition: TcpLayer.h:40
uint16_t portDst
Destination TCP port.
Definition: TcpLayer.h:25
uint16_t portSrc
Source TCP port.
Definition: TcpLayer.h:23
uint16_t reserved
Reserved bits.
Definition: TcpLayer.h:34
uint16_t dataOffset
Specifies the size of the TCP header in 32-bit words.
Definition: TcpLayer.h:36
uint16_t eceFlag
ECE flag.
Definition: TcpLayer.h:50
uint16_t windowSize
The size of the receive window, which specifies the number of window size units (by default,...
Definition: TcpLayer.h:80
uint16_t finFlag
FIN flag.
Definition: TcpLayer.h:38
uint16_t ackFlag
ACK flag.
Definition: TcpLayer.h:46
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:82