PcapPlusPlus  24.09
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 
17 namespace pcpp
18 {
19 
24 #pragma pack(push, 1)
25  struct tcphdr
26  {
28  uint16_t portSrc;
30  uint16_t portDst;
32  uint32_t sequenceNumber;
34  uint32_t ackNumber;
35 #if (BYTE_ORDER == LITTLE_ENDIAN)
36  uint16_t reserved : 4;
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 : 4;
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 
92  enum TcpOptionType : uint8_t
93  {
113  TCPOPT_CC = 11,
121  TCPOPT_MPTCP = 0x1e,
131  TCPOPT_QS = 27,
143  TCPOPT_Unknown = 255
144  };
145 
149  enum class TcpOptionEnumType : uint8_t
150  {
152  Nop = 1,
154  Eol = 0,
156  Mss = 2,
158  Window = 3,
160  SackPerm = 4,
162  Sack = 5,
164  Echo = 6,
166  EchoReply = 7,
168  Timestamp = 8,
170  Cc = 11,
172  CcNew = 12,
174  CcEcho = 13,
176  Md5 = 19,
178  MpTcp = 0x1e,
180  Scps = 20,
182  Snack = 21,
184  RecBound = 22,
186  CorrExp = 23,
188  Qs = 27,
190  UserTo = 28,
192  ExpFd = 0xfd,
194  ExpFe = 0xfe,
196  RvbdProbe = 76,
198  RvbdTrpy = 78,
200  Unknown = 255
201  };
202 
203  // TCP option lengths
204 
206 #define PCPP_TCPOLEN_NOP 1
208 #define PCPP_TCPOLEN_EOL 1
210 #define PCPP_TCPOLEN_MSS 4
212 #define PCPP_TCPOLEN_WINDOW 3
214 #define PCPP_TCPOLEN_SACK_PERM 2
216 #define PCPP_TCPOLEN_SACK_MIN 2
218 #define PCPP_TCPOLEN_ECHO 6
220 #define PCPP_TCPOLEN_ECHOREPLY 6
222 #define PCPP_TCPOLEN_TIMESTAMP 10
224 #define PCPP_TCPOLEN_CC 6
226 #define PCPP_TCPOLEN_CCNEW 6
228 #define PCPP_TCPOLEN_CCECHO 6
230 #define PCPP_TCPOLEN_MD5 18
232 #define PCPP_TCPOLEN_MPTCP_MIN 8
234 #define PCPP_TCPOLEN_SCPS 4
236 #define PCPP_TCPOLEN_SNACK 6
238 #define PCPP_TCPOLEN_RECBOUND 2
240 #define PCPP_TCPOLEN_CORREXP 2
242 #define PCPP_TCPOLEN_QS 8
244 #define PCPP_TCPOLEN_USER_TO 4
246 #define PCPP_TCPOLEN_RVBD_PROBE_MIN 3
248 #define PCPP_TCPOLEN_RVBD_TRPY_MIN 16
250 #define PCPP_TCPOLEN_EXP_MIN 2
251 
257  class TcpOption : public TLVRecord<uint8_t, uint8_t>
258  {
259  public:
264  explicit TcpOption(uint8_t* optionRawData) : TLVRecord(optionRawData)
265  {}
266 
270  ~TcpOption() = default;
271 
275  PCPP_DEPRECATED("Use getTcpOptionEnumType instead")
277  {
278  return getTcpOptionType(m_Data);
279  }
280 
286  {
287  return getTcpOptionEnumType(m_Data);
288  }
289 
296  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
297  {
298  const auto* data = reinterpret_cast<const TLVRawData*>(recordRawData);
299  if (data == nullptr)
300  return false;
301 
302  if (tlvDataLen < sizeof(TLVRawData::recordType))
303  return false;
304 
305  const auto recordType = getTcpOptionEnumType(data);
306  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
307  return true;
308 
309  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
310  }
311 
312  // implement abstract methods
313 
314  size_t getTotalSize() const
315  {
316  if (m_Data == nullptr)
317  return 0;
318 
319  const auto recordType = getTcpOptionEnumType(m_Data);
320  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
321  return sizeof(uint8_t);
322 
323  return static_cast<size_t>(m_Data->recordLen);
324  }
325 
326  size_t getDataSize() const
327  {
328  if (m_Data == nullptr)
329  return 0;
330 
331  const auto recordType = getTcpOptionEnumType(m_Data);
332  if (recordType == TcpOptionEnumType::Nop || recordType == TcpOptionEnumType::Eol)
333  return 0;
334 
335  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
336  }
337 
338  private:
339  static TcpOptionType getTcpOptionType(const TLVRawData* optionRawData)
340  {
341  if (optionRawData == nullptr)
343 
344  return static_cast<TcpOptionType>(optionRawData->recordType);
345  }
346 
347  static TcpOptionEnumType getTcpOptionEnumType(const TLVRawData* optionRawData)
348  {
349  if (optionRawData == nullptr)
351 
352  return static_cast<TcpOptionEnumType>(optionRawData->recordType);
353  }
354  };
355 
362  {
363 
364  public:
368  enum NopEolOptionTypes : uint8_t
369  {
373  EOL
374  };
375 
379  enum class NopEolOptionEnumType : uint8_t
380  {
382  Nop,
384  Eol
385  };
386 
390  PCPP_DEPRECATED_TCP_OPTION_TYPE
391  TcpOptionBuilder(TcpOptionType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
392  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
393  {}
394 
403  TcpOptionBuilder(TcpOptionEnumType optionType, const uint8_t* optionValue, uint8_t optionValueLen)
404  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue, optionValueLen)
405  {}
406 
410  PCPP_DEPRECATED_TCP_OPTION_TYPE
411  TcpOptionBuilder(TcpOptionType optionType, uint8_t optionValue)
412  : TLVRecordBuilder((uint8_t)optionType, optionValue)
413  {}
414 
421  TcpOptionBuilder(TcpOptionEnumType optionType, uint8_t optionValue)
422  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
423  {}
424 
428  PCPP_DEPRECATED_TCP_OPTION_TYPE
429  TcpOptionBuilder(TcpOptionType optionType, uint16_t optionValue)
430  : TLVRecordBuilder((uint8_t)optionType, optionValue)
431  {}
432 
439  TcpOptionBuilder(TcpOptionEnumType optionType, uint16_t optionValue)
440  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
441  {}
442 
446  PCPP_DEPRECATED_TCP_OPTION_TYPE
447  TcpOptionBuilder(TcpOptionType optionType, uint32_t optionValue)
448  : TLVRecordBuilder((uint8_t)optionType, optionValue)
449  {}
450 
457  TcpOptionBuilder(TcpOptionEnumType optionType, uint32_t optionValue)
458  : TLVRecordBuilder(static_cast<uint8_t>(optionType), optionValue)
459  {}
460 
464  PCPP_DEPRECATED("enum NopEolOptionTypes is deprecated; Use enum class NopEolOptionEnumType instead")
465  explicit TcpOptionBuilder(NopEolOptionTypes optionType);
466 
474 
479  TcpOption build() const;
480  };
481 
486  class TcpLayer : public Layer
487  {
488  public:
496  TcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
497 
502 
508  TcpLayer(uint16_t portSrc, uint16_t portDst);
509 
510  ~TcpLayer() = default;
511 
515  TcpLayer(const TcpLayer& other);
516 
521  TcpLayer& operator=(const TcpLayer& other);
522 
529  {
530  return (tcphdr*)m_Data;
531  }
532 
536  uint16_t getSrcPort() const;
537 
541  uint16_t getDstPort() const;
542 
546  PCPP_DEPRECATED_TCP_OPTION_TYPE
547  TcpOption getTcpOption(TcpOptionType option) const;
548 
556 
562 
571 
575  size_t getTcpOptionCount() const;
576 
584  TcpOption addTcpOption(const TcpOptionBuilder& optionBuilder);
585 
590  PCPP_DEPRECATED("Use insertTcpOptionAfter instead")
591  TcpOption addTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
592  TcpOptionType prevOptionType = TcpOptionType::TCPOPT_Unknown);
593 
604  TcpOption insertTcpOptionAfter(const TcpOptionBuilder& optionBuilder,
605  TcpOptionEnumType prevOptionType = TcpOptionEnumType::Unknown);
606 
610  PCPP_DEPRECATED_TCP_OPTION_TYPE
611  bool removeTcpOption(TcpOptionType optionType);
612 
619  bool removeTcpOption(TcpOptionEnumType optionType);
620 
626  bool removeAllTcpOptions();
627 
634  uint16_t calculateChecksum(bool writeResultToPacket);
635 
642  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
643 
644  // implement abstract methods
645 
650  void parseNextLayer();
651 
655  size_t getHeaderLen() const
656  {
657  return getTcpHeader()->dataOffset * 4;
658  }
659 
664 
665  std::string toString() const;
666 
668  {
669  return OsiModelTransportLayer;
670  }
671 
672  private:
673  TLVRecordReader<TcpOption> m_OptionReader;
674  int m_NumOfTrailingBytes;
675 
676  void initLayer();
677  uint8_t* getOptionsBasePtr() const
678  {
679  return m_Data + sizeof(tcphdr);
680  }
681  TcpOption addTcpOptionAt(const TcpOptionBuilder& optionBuilder, int offset);
682  void adjustTcpOptionTrailer(size_t totalOptSize);
683  void copyLayerData(const TcpLayer& other);
684  };
685 
686  // implementation of inline methods
687 
688  bool TcpLayer::isDataValid(const uint8_t* data, size_t dataLen)
689  {
690  const tcphdr* hdr = reinterpret_cast<const tcphdr*>(data);
691  return dataLen >= sizeof(tcphdr) && hdr->dataOffset >= 5 /* the minimum TCP header size */
692  && dataLen >= hdr->dataOffset * sizeof(uint32_t);
693  }
694 } // namespace pcpp
695 
696 #undef PCPP_DEPRECATED_TCP_OPTION_TYPE
Definition: Layer.h:70
Definition: Packet.h:27
Definition: TLVData.h:413
Definition: TLVData.h:23
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:79
Definition: TLVData.h:239
Definition: TcpLayer.h:487
tcphdr * getTcpHeader() const
Definition: TcpLayer.h:528
uint16_t getSrcPort() const
TcpOption getTcpOption(TcpOptionEnumType option) const
TcpOption getFirstTcpOption() const
void computeCalculateFields()
TcpLayer(const TcpLayer &other)
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)
TcpLayer(uint16_t portSrc, uint16_t portDst)
OsiModelLayer getOsiModelLayer() const
Definition: TcpLayer.h:667
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: TcpLayer.h:688
size_t getTcpOptionCount() const
TcpOption getNextTcpOption(TcpOption &tcpOption) const
std::string toString() const
Definition: TcpLayer.h:362
PCPP_DEPRECATED("enum TcpOptionType is deprecated; Use enum class TcpOptionEnumType instead") TcpOptionBuilder(TcpOptionType optionType
NopEolOptionEnumType
Definition: TcpLayer.h:380
TcpOptionBuilder(NopEolOptionEnumType optionType)
NopEolOptionTypes
Definition: TcpLayer.h:369
@ EOL
Definition: TcpLayer.h:373
@ NOP
Definition: TcpLayer.h:371
TcpOption build() const
Definition: TcpLayer.h:258
TcpOptionEnumType getTcpOptionEnumType() const
Definition: TcpLayer.h:285
TcpOptionType getTcpOptionType() const
Definition: TcpLayer.h:276
~TcpOption()=default
size_t getTotalSize() const
Definition: TcpLayer.h:314
size_t getDataSize() const
Definition: TcpLayer.h:326
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TcpLayer.h:296
TcpOption(uint8_t *optionRawData)
Definition: TcpLayer.h:264
The main namespace for the PcapPlusPlus lib.
TcpOptionEnumType
Definition: TcpLayer.h:150
OsiModelLayer
Definition: ProtocolType.h:354
@ OsiModelTransportLayer
Definition: ProtocolType.h:362
TcpOptionType
Definition: TcpLayer.h:93
@ TCPOPT_EXP_FD
Definition: TcpLayer.h:135
@ TCPOPT_USER_TO
Definition: TcpLayer.h:133
@ TCPOPT_SCPS
Definition: TcpLayer.h:123
@ TCPOPT_MSS
Definition: TcpLayer.h:99
@ PCPP_TCPOPT_NOP
Definition: TcpLayer.h:95
@ TCPOPT_QS
Definition: TcpLayer.h:131
@ PCPP_TCPOPT_WINDOW
Definition: TcpLayer.h:101
@ TCPOPT_CCNEW
Definition: TcpLayer.h:115
@ TCPOPT_RVBD_TRPY
Definition: TcpLayer.h:141
@ PCPP_TCPOPT_EOL
Definition: TcpLayer.h:97
@ TCPOPT_Unknown
Definition: TcpLayer.h:143
@ TCPOPT_MPTCP
Definition: TcpLayer.h:121
@ TCPOPT_EXP_FE
Definition: TcpLayer.h:137
@ TCPOPT_CC
Definition: TcpLayer.h:113
@ TCPOPT_ECHOREPLY
Definition: TcpLayer.h:109
@ TCPOPT_RVBD_PROBE
Definition: TcpLayer.h:139
@ TCPOPT_MD5
Definition: TcpLayer.h:119
@ TCPOPT_SNACK
Definition: TcpLayer.h:125
@ PCPP_TCPOPT_TIMESTAMP
Definition: TcpLayer.h:111
@ TCPOPT_CORREXP
Definition: TcpLayer.h:129
@ TCPOPT_RECBOUND
Definition: TcpLayer.h:127
@ TCPOPT_SACK_PERM
Definition: TcpLayer.h:103
@ TCPOPT_CCECHO
Definition: TcpLayer.h:117
@ PCPP_TCPOPT_SACK
Definition: TcpLayer.h:105
@ TCPOPT_ECHO
Definition: TcpLayer.h:107
Definition: TcpLayer.h:26
uint16_t pshFlag
Definition: TcpLayer.h:46
uint16_t cwrFlag
Definition: TcpLayer.h:54
uint16_t urgFlag
Definition: TcpLayer.h:50
uint32_t sequenceNumber
Definition: TcpLayer.h:32
uint16_t rstFlag
Definition: TcpLayer.h:44
uint16_t urgentPointer
Definition: TcpLayer.h:85
uint16_t synFlag
Definition: TcpLayer.h:42
uint16_t portDst
Definition: TcpLayer.h:30
uint16_t portSrc
Definition: TcpLayer.h:28
uint16_t dataOffset
Definition: TcpLayer.h:38
uint16_t eceFlag
Definition: TcpLayer.h:52
uint16_t windowSize
Definition: TcpLayer.h:80
uint16_t finFlag
Definition: TcpLayer.h:40
uint16_t ackFlag
Definition: TcpLayer.h:48
uint32_t ackNumber
Definition: TcpLayer.h:34
uint16_t headerChecksum
Definition: TcpLayer.h:82