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 #include <algorithm>
8 #include <iterator>
9 
10 #define PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG \
11  "enum TcpOptionType is deprecated; Use enum class TcpOptionEnumType instead"
12 
14 
17 namespace pcpp
18 {
21 #pragma pack(push, 1)
22  struct tcphdr
23  {
25  uint16_t portSrc;
27  uint16_t portDst;
29  uint32_t sequenceNumber;
31  uint32_t ackNumber;
32 #if (BYTE_ORDER == LITTLE_ENDIAN)
34  uint16_t accurateEcnFlag : 1;
36  uint16_t reserved : 3;
38  uint16_t dataOffset : 4;
40  uint16_t finFlag : 1;
42  uint16_t synFlag : 1;
44  uint16_t rstFlag : 1;
46  uint16_t pshFlag : 1;
48  uint16_t ackFlag : 1;
50  uint16_t urgFlag : 1;
52  uint16_t eceFlag : 1;
54  uint16_t cwrFlag : 1;
55 #elif (BYTE_ORDER == BIG_ENDIAN)
57  uint16_t dataOffset : 4;
59  uint16_t reserved : 3;
61  uint16_t accurateEcnFlag : 1;
63  uint16_t cwrFlag : 1;
65  uint16_t eceFlag : 1;
67  uint16_t urgFlag : 1;
69  uint16_t ackFlag : 1;
71  uint16_t pshFlag : 1;
73  uint16_t rstFlag : 1;
75  uint16_t synFlag : 1;
77  uint16_t finFlag : 1;
78 #else
79 # error "Endian is not LE nor BE..."
80 #endif
82  uint16_t windowSize;
84  uint16_t headerChecksum;
87  uint16_t urgentPointer;
88  };
89 #pragma pack(pop)
90  static_assert(sizeof(tcphdr) == 20, "tcphdr size is not 20 bytes");
91 
93  enum TcpOptionType : uint8_t
94  {
114  TCPOPT_CC = 11,
122  TCPOPT_MPTCP = 0x1e,
132  TCPOPT_QS = 27,
144  TCPOPT_Unknown = 255
145  };
146 
148  enum class TcpOptionEnumType : uint8_t
149  {
151  Nop = 1,
153  Eol = 0,
155  Mss = 2,
157  Window = 3,
159  SackPerm = 4,
161  Sack = 5,
163  Echo = 6,
165  EchoReply = 7,
167  Timestamp = 8,
169  Cc = 11,
171  CcNew = 12,
173  CcEcho = 13,
175  Md5 = 19,
177  MpTcp = 0x1e,
179  Scps = 20,
181  Snack = 21,
183  RecBound = 22,
185  CorrExp = 23,
187  Qs = 27,
189  UserTo = 28,
191  ExpFd = 0xfd,
193  ExpFe = 0xfe,
195  RvbdProbe = 76,
197  RvbdTrpy = 78,
199  Unknown = 255
200  };
201 
202  // TCP option lengths
203 
205 #define PCPP_TCPOLEN_NOP 1
207 #define PCPP_TCPOLEN_EOL 1
209 #define PCPP_TCPOLEN_MSS 4
211 #define PCPP_TCPOLEN_WINDOW 3
213 #define PCPP_TCPOLEN_SACK_PERM 2
215 #define PCPP_TCPOLEN_SACK_MIN 2
217 #define PCPP_TCPOLEN_ECHO 6
219 #define PCPP_TCPOLEN_ECHOREPLY 6
221 #define PCPP_TCPOLEN_TIMESTAMP 10
223 #define PCPP_TCPOLEN_CC 6
225 #define PCPP_TCPOLEN_CCNEW 6
227 #define PCPP_TCPOLEN_CCECHO 6
229 #define PCPP_TCPOLEN_MD5 18
231 #define PCPP_TCPOLEN_MPTCP_MIN 8
233 #define PCPP_TCPOLEN_SCPS 4
235 #define PCPP_TCPOLEN_SNACK 6
237 #define PCPP_TCPOLEN_RECBOUND 2
239 #define PCPP_TCPOLEN_CORREXP 2
241 #define PCPP_TCPOLEN_QS 8
243 #define PCPP_TCPOLEN_USER_TO 4
245 #define PCPP_TCPOLEN_RVBD_PROBE_MIN 3
247 #define PCPP_TCPOLEN_RVBD_TRPY_MIN 16
249 #define PCPP_TCPOLEN_EXP_MIN 2
250 
254  class TcpOption : public TLVRecord<uint8_t, uint8_t>
255  {
256  public:
259  explicit TcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData)
260  {}
261 
263  ~TcpOption() override = default;
264 
266  PCPP_DEPRECATED("Use getTcpOptionEnumType instead")
268  {
269  return getTcpOptionType(m_Data);
270  }
271 
275  {
276  return getTcpOptionEnumType(m_Data);
277  }
278 
283  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
284  {
285  const auto* data = reinterpret_cast<const TLVRawData*>(recordRawData);
286  if (data == nullptr)
287  return false;
288 
289  if (tlvDataLen < sizeof(TLVRawData::recordType))
290  return false;
291 
292  const auto recordType = getTcpOptionEnumType(data);
293  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
294  return true;
295 
296  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
297  }
298 
299  // implement abstract methods
300 
301  size_t getTotalSize() const override
302  {
303  if (m_Data == nullptr)
304  return 0;
305 
306  const auto recordType = getTcpOptionEnumType(m_Data);
307  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
308  return sizeof(uint8_t);
309 
310  return static_cast<size_t>(m_Data->recordLen);
311  }
312 
313  size_t getDataSize() const override
314  {
315  if (m_Data == nullptr)
316  return 0;
317 
318  const auto recordType = getTcpOptionEnumType(m_Data);
319  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
320  return 0;
321 
322  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
323  }
324 
325  private:
326  static TcpOptionType getTcpOptionType(const TLVRawData* optionRawData)
327  {
328  if (optionRawData == nullptr)
330 
331  return static_cast<TcpOptionType>(optionRawData->recordType);
332  }
333 
334  static TcpOptionEnumType getTcpOptionEnumType(const TLVRawData* optionRawData)
335  {
336  if (optionRawData == nullptr)
338 
339  return static_cast<TcpOptionEnumType>(optionRawData->recordType);
340  }
341  };
342 
347  {
348 
349  public:
351  enum NopEolOptionTypes : uint8_t
352  {
356  EOL
357  };
358 
360  enum class NopEolOptionEnumType : uint8_t
361  {
363  Nop,
365  Eol
366  };
367 
369  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
370  TcpOptionBuilder(TcpOptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
371  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
372  {}
373 
380  TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
381  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
382  {}
383 
385  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
386  TcpOptionBuilder(TcpOptionType optionType, uint8_t optionValue)
387  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
388  {}
389 
394  TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue)
395  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
396  {}
397 
399  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
400  TcpOptionBuilder(TcpOptionType optionType, uint16_t optionValue)
401  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
402  {}
403 
408  TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue)
409  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
410  {}
411 
413  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
414  TcpOptionBuilder(TcpOptionType optionType, uint32_t optionValue)
415  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
416  {}
417 
422  TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue)
423  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
424  {}
425 
427  PCPP_DEPRECATED("enum NopEolOptionTypes is deprecated; Use enum class NopEolOptionEnumType instead")
428  explicit TcpOptionBuilder(NopEolOptionTypes optionType);
429 
435 
438  TcpOption build() const;
439  };
440 
443  class TcpLayer : public Layer
444  {
445  public:
451  TcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
452 
455 
459  TcpLayer(uint16_t portSrc, uint16_t portDst);
460 
461  ~TcpLayer() override = default;
462 
464  TcpLayer(const TcpLayer& other);
465 
468  TcpLayer& operator=(const TcpLayer& other);
469 
474  {
475  return reinterpret_cast<tcphdr*>(m_Data);
476  }
477 
479  uint16_t getSrcPort() const;
480 
482  uint16_t getDstPort() const;
483 
485  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
486  TcpOption getTcpOption(TcpOptionType option) const;
487 
492  TcpOption getTcpOption(TcpOptionEnumType option) const;
493 
496  TcpOption getFirstTcpOption() const;
497 
503  TcpOption getNextTcpOption(TcpOption& tcpOption) const;
504 
506  size_t getTcpOptionCount() const;
507 
513  TcpOption addTcpOption(const TcpOptionBuilder& optionBuilder);
514 
517  PCPP_DEPRECATED("Use insertTcpOptionAfter instead")
518  TcpOption addTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
519  TcpOptionType prevOptionType = TcpOptionType::TCPOPT_Unknown);
520 
530  TcpOption insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
531  TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown);
532 
534  PCPP_DEPRECATED(PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG)
535  bool removeTcpOption(TcpOptionType optionType);
536 
541  bool removeTcpOption(TcpOptionEnumType optionType);
542 
546  bool removeAllTcpOptions();
547 
552  uint16_t calculateChecksum(bool writeResultToPacket);
553 
558  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
559 
560  // implement abstract methods
561 
564  void parseNextLayer() override;
565 
567  size_t getHeaderLen() const override
568  {
569  return getTcpHeader()->dataOffset * 4;
570  }
571 
573  void computeCalculateFields() override;
574 
575  std::string toString() const override;
576 
578  {
579  return OsiModelTransportLayer;
580  }
581 
586  {
588  static std::vector<FieldDescriptor> all()
589  {
590  auto result = Layer::SerializedFields::all();
591  std::initializer_list<FieldDescriptor> extra{ SrcPort, DstPort, SequenceNumber, TcpFlags,
592  WindowSize, Checksum, Options };
593  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
594  return result;
595  }
596 
598  static const FieldDescriptor SrcPort;
599 
601  static const FieldDescriptor DstPort;
602 
605 
607  static const FieldDescriptor TcpFlags;
608 
610  static const FieldDescriptor TcpFlag;
611 
614 
616  static const FieldDescriptor Checksum;
617 
619  static const FieldDescriptor Options;
620 
623  static const FieldDescriptor Option;
624  };
625 
626  protected:
627  void serializeLayer(ObjectScope& serializer) const override;
628 
629  private:
630  TLVRecordReader<TcpOption> m_OptionReader;
631  int m_NumOfTrailingBytes;
632 
633  void initLayer();
634  uint8_t* getOptionsBasePtr() const
635  {
636  return m_Data + sizeof(tcphdr);
637  }
638  TcpOption addTcpOptionAt(const TcpOptionBuilder& optionBuilder, int offset);
639  void adjustTcpOptionTrailer(size_t totalOptSize);
640  void copyLayerData(const TcpLayer& other);
641  };
642 
643  // implementation of inline methods
644 
645  bool TcpLayer::isDataValid(const uint8_t* data, size_t dataLen)
646  {
647  const tcphdr* hdr = reinterpret_cast<const tcphdr*>(data);
648  return dataLen >= sizeof(tcphdr) && hdr->dataOffset >= 5 /* the minimum TCP header size */
649  && dataLen >= hdr->dataOffset * sizeof(uint32_t);
650  }
651 } // namespace pcpp
652 
653 #undef PCPP_INTERNAL_DEPRECATE_TCP_OPTION_TYPE_MSG
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: Packet.h:49
Definition: TLVData.h:374
Definition: TLVData.h:20
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:67
Definition: TLVData.h:219
Definition: TcpLayer.h:444
tcphdr * getTcpHeader() const
Definition: TcpLayer.h:473
OsiModelLayer getOsiModelLayer() const override
Definition: TcpLayer.h:577
uint16_t getSrcPort() const
TcpLayer()
A constructor that allocates a new TCP header with zero TCP options.
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)
void computeCalculateFields() override
Calculate tcphdr::headerChecksum field.
TcpLayer(uint16_t portSrc, uint16_t portDst)
void serializeLayer(ObjectScope &serializer) const override
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: TcpLayer.h:645
std::string toString() const override
Definition: TcpLayer.h:347
NopEolOptionEnumType
An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors.
Definition: TcpLayer.h:361
NopEolOptionTypes
An enum to describe NOP and EOL TCP options. Used in one of this class's c'tors.
Definition: TcpLayer.h:352
@ EOL
EOL TCP option.
Definition: TcpLayer.h:356
@ NOP
NOP TCP option.
Definition: TcpLayer.h:354
TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue)
Definition: TcpLayer.h:408
TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: TcpLayer.h:380
TcpOption build() const
TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue)
Definition: TcpLayer.h:422
TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue)
Definition: TcpLayer.h:394
Definition: TcpLayer.h:255
TcpOptionEnumType getTcpOptionEnumType() const
Definition: TcpLayer.h:274
TcpOptionType getTcpOptionType() const
Definition: TcpLayer.h:267
size_t getTotalSize() const override
Definition: TcpLayer.h:301
size_t getDataSize() const override
Definition: TcpLayer.h:313
~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:283
TcpOption(uint8_t *optionRawData)
Definition: TcpLayer.h:259
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
TcpOptionEnumType
TCP options types.
Definition: TcpLayer.h:149
@ 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:420
@ PCPP_DEPRECATED
Deprecated typo, use OsiModelSessionLayer instead.
Definition: ProtocolType.h:432
@ OsiModelTransportLayer
Transport layer (layer 4)
Definition: ProtocolType.h:428
SSLSymmetricEncryptionAlgorithm
SSL/TLS symmetric encryption algorithms.
Definition: SSLCommon.h:355
TcpOptionType
TCP options types.
Definition: TcpLayer.h:94
@ TCPOPT_EXP_FD
RFC3692-style Experiment 1 (also improperly used for shipping products)
Definition: TcpLayer.h:136
@ TCPOPT_USER_TO
User Timeout Option (also, other known unauthorized use)
Definition: TcpLayer.h:134
@ TCPOPT_SCPS
SCPS Capabilities.
Definition: TcpLayer.h:124
@ TCPOPT_MSS
Segment size negotiating.
Definition: TcpLayer.h:100
@ PCPP_TCPOPT_NOP
Padding.
Definition: TcpLayer.h:96
@ TCPOPT_QS
Quick-Start Response.
Definition: TcpLayer.h:132
@ PCPP_TCPOPT_WINDOW
Window scaling.
Definition: TcpLayer.h:102
@ TCPOPT_CCNEW
CC.NEW (obsolete)
Definition: TcpLayer.h:116
@ TCPOPT_RVBD_TRPY
Riverbed transparency option, non IANA registered option number.
Definition: TcpLayer.h:142
@ PCPP_TCPOPT_EOL
End of options.
Definition: TcpLayer.h:98
@ TCPOPT_Unknown
Unknown option.
Definition: TcpLayer.h:144
@ TCPOPT_MPTCP
Multipath TCP.
Definition: TcpLayer.h:122
@ TCPOPT_EXP_FE
RFC3692-style Experiment 2 (also improperly used for shipping products)
Definition: TcpLayer.h:138
@ TCPOPT_CC
CC (obsolete)
Definition: TcpLayer.h:114
@ TCPOPT_ECHOREPLY
Echo Reply (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:110
@ TCPOPT_RVBD_PROBE
Riverbed probe option, non IANA registered option number.
Definition: TcpLayer.h:140
@ TCPOPT_MD5
MD5 Signature Option.
Definition: TcpLayer.h:120
@ TCPOPT_SNACK
SCPS SNACK.
Definition: TcpLayer.h:126
@ PCPP_TCPOPT_TIMESTAMP
TCP Timestamps.
Definition: TcpLayer.h:112
@ TCPOPT_CORREXP
SCPS Corruption Experienced.
Definition: TcpLayer.h:130
@ TCPOPT_RECBOUND
SCPS Record Boundary.
Definition: TcpLayer.h:128
@ TCPOPT_SACK_PERM
SACK Permitted.
Definition: TcpLayer.h:104
@ TCPOPT_CCECHO
CC.ECHO(obsolete)
Definition: TcpLayer.h:118
@ PCPP_TCPOPT_SACK
SACK Block.
Definition: TcpLayer.h:106
@ TCPOPT_ECHO
Echo (obsoleted by option TcpOptionType::PCPP_TCPOPT_TIMESTAMP)
Definition: TcpLayer.h:108
Definition: Serializers.h:18
Definition: Layer.h:212
static std::vector< FieldDescriptor > all()
Definition: Layer.h:214
Definition: TcpLayer.h:586
static const FieldDescriptor Checksum
Checksum, as a hex string.
Definition: TcpLayer.h:616
static const FieldDescriptor Option
Definition: TcpLayer.h:623
static const FieldDescriptor Options
Array of header options; elements described by Option.
Definition: TcpLayer.h:619
static std::vector< FieldDescriptor > all()
Definition: TcpLayer.h:588
static const FieldDescriptor DstPort
Destination port, in host byte order.
Definition: TcpLayer.h:601
static const FieldDescriptor TcpFlags
Array of set flag names (e.g. "SYN", "ACK"); elements described by TcpFlag.
Definition: TcpLayer.h:607
static const FieldDescriptor SrcPort
Source port, in host byte order.
Definition: TcpLayer.h:598
static const FieldDescriptor TcpFlag
One set flag's name; a TcpFlags element, not in all()
Definition: TcpLayer.h:610
static const FieldDescriptor SequenceNumber
Sequence number, in host byte order.
Definition: TcpLayer.h:604
static const FieldDescriptor WindowSize
Window size, in host byte order.
Definition: TcpLayer.h:613
Definition: TcpLayer.h:23
uint16_t pshFlag
PSH flag.
Definition: TcpLayer.h:46
uint16_t cwrFlag
CWR flag.
Definition: TcpLayer.h:54
uint16_t urgFlag
URG flag.
Definition: TcpLayer.h:50
uint32_t sequenceNumber
Sequence number.
Definition: TcpLayer.h:29
uint16_t accurateEcnFlag
Accurate ECN flag.
Definition: TcpLayer.h:34
uint16_t rstFlag
RST flag.
Definition: TcpLayer.h:44
uint16_t urgentPointer
Definition: TcpLayer.h:87
uint16_t synFlag
SYN flag.
Definition: TcpLayer.h:42
uint16_t portDst
Destination TCP port.
Definition: TcpLayer.h:27
uint16_t portSrc
Source TCP port.
Definition: TcpLayer.h:25
uint16_t reserved
Reserved bits.
Definition: TcpLayer.h:36
uint16_t dataOffset
Specifies the size of the TCP header in 32-bit words.
Definition: TcpLayer.h:38
uint16_t eceFlag
ECE flag.
Definition: TcpLayer.h:52
uint16_t windowSize
The size of the receive window, which specifies the number of window size units (by default,...
Definition: TcpLayer.h:82
uint16_t finFlag
FIN flag.
Definition: TcpLayer.h:40
uint16_t ackFlag
ACK flag.
Definition: TcpLayer.h:48
uint32_t ackNumber
Acknowledgment number.
Definition: TcpLayer.h:31
uint16_t headerChecksum
The 16-bit checksum field is used for error-checking of the header and data.
Definition: TcpLayer.h:84