libtins  4.0
tcp.h
1 /*
2  * Copyright (c) 2017, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #ifndef TINS_TCP_H
31 #define TINS_TCP_H
32 
33 #include <vector>
34 #include <stdint.h>
35 #include <utility>
36 #include <tins/pdu.h>
37 #include <tins/macros.h>
38 #include <tins/endianness.h>
39 #include <tins/small_uint.h>
40 #include <tins/pdu_option.h>
41 #include <tins/cxxstd.h>
42 
43 namespace Tins {
44 namespace Memory {
45 class OutputMemoryStream;
46 } // Memory
47 
76 class TINS_API TCP : public PDU {
77 public:
81  static const PDU::PDUType pdu_flag = PDU::TCP;
82 
88  enum Flags {
89  FIN = 1,
90  SYN = 2,
91  RST = 4,
92  PSH = 8,
93  ACK = 16,
94  URG = 32,
95  ECE = 64,
96  CWR = 128
97  };
98 
104  enum OptionTypes {
105  EOL = 0,
106  NOP = 1,
107  MSS = 2,
108  WSCALE = 3,
109  SACK_OK = 4,
110  SACK = 5,
111  TSOPT = 8,
112  ALTCHK = 14,
113  RFC_EXPERIMENT_1 = 253,
114  RFC_EXPERIMENT_2 = 254
115  };
116 
121  CHK_TCP,
122  CHK_8FLETCHER,
123  CHK_16FLETCHER
124  };
125 
130 
134  typedef std::vector<option> options_type;
135 
139  typedef std::vector<uint32_t> sack_type;
140 
147  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
148 
158  TCP(uint16_t dport = 0, uint16_t sport = 0);
159 
172  TCP(const uint8_t* buffer, uint32_t total_sz);
173 
179  uint16_t dport() const {
180  return Endian::be_to_host(header_.dport);
181  }
182 
188  uint16_t sport() const {
189  return Endian::be_to_host(header_.sport);
190  }
191 
197  uint32_t seq() const {
198  return Endian::be_to_host(header_.seq);
199  }
200 
206  uint32_t ack_seq() const {
207  return Endian::be_to_host(header_.ack_seq);
208  }
209 
215  uint16_t window() const {
216  return Endian::be_to_host(header_.window);
217  }
218 
224  uint16_t checksum() const {
225  return Endian::be_to_host(header_.check);
226  }
227 
233  uint16_t urg_ptr() const {
234  return Endian::be_to_host(header_.urg_ptr);
235  }
236 
243  return this->header_.doff;
244  }
245 
251  const options_type& options() const {
252  return options_;
253  }
254 
278  small_uint<1> get_flag(Flags tcp_flag) const;
279 
297  small_uint<12> flags() const;
298 
299  /* Setters */
300 
306  void dport(uint16_t new_dport);
307 
313  void sport(uint16_t new_sport);
314 
320  void seq(uint32_t new_seq);
321 
327  void ack_seq(uint32_t new_ack_seq);
328 
334  void window(uint16_t new_window);
335 
341  void urg_ptr(uint16_t new_urg_ptr);
342 
348  void data_offset(small_uint<4> new_doff);
349 
350  // Options
351 
357  void mss(uint16_t value);
358 
364  uint16_t mss() const;
365 
371  void winscale(uint8_t value);
372 
378  uint8_t winscale() const;
379 
383  void sack_permitted();
384 
389  bool has_sack_permitted() const;
390 
396  void sack(const sack_type& edges);
397 
403  sack_type sack() const;
404 
411  void timestamp(uint32_t value, uint32_t reply);
412 
419  std::pair<uint32_t, uint32_t> timestamp() const;
420 
426  void altchecksum(AltChecksums value);
427 
433  AltChecksums altchecksum() const;
434 
441  void set_flag(Flags tcp_flag, small_uint<1> value);
442 
461  void flags(small_uint<12> value);
462 
463 
469  void add_option(const option& opt);
470 
471  #if TINS_IS_CXX11
472 
479  void add_option(option &&opt) {
480  options_.push_back(std::move(opt));
481  }
482 
491  template <typename... Args>
492  void add_option(Args&&... args) {
493  options_.emplace_back(std::forward<Args>(args)...);
494  }
495  #endif
496 
506  bool remove_option(OptionTypes type);
507 
516  uint32_t header_size() const;
517 
525  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
526 
532  PDUType pdu_type() const {
533  return pdu_flag;
534  }
535 
541  const option* search_option(OptionTypes type) const;
542 
546  TCP* clone() const {
547  return new TCP(*this);
548  }
549 private:
550  #if TINS_IS_LITTLE_ENDIAN
551  TINS_BEGIN_PACK
552  struct flags_type {
553  uint8_t fin:1,
554  syn:1,
555  rst:1,
556  psh:1,
557  ack:1,
558  urg:1,
559  ece:1,
560  cwr:1;
561  } TINS_END_PACK;
562  #else
563  TINS_BEGIN_PACK
564  struct flags_type {
565  uint8_t cwr:1,
566  ece:1,
567  urg:1,
568  ack:1,
569  psh:1,
570  rst:1,
571  syn:1,
572  fin:1;
573  } TINS_END_PACK;
574  #endif
575 
576  TINS_BEGIN_PACK
577  struct tcp_header {
578  uint16_t sport;
579  uint16_t dport;
580  uint32_t seq;
581  uint32_t ack_seq;
582  #if TINS_IS_LITTLE_ENDIAN
583  uint8_t res1:4,
584  doff:4;
585  #else
586  uint8_t doff:4,
587  res1:4;
588  #endif
589  union {
590  flags_type flags;
591  uint8_t flags_8;
592  };
593  uint16_t window;
594  uint16_t check;
595  uint16_t urg_ptr;
596  } TINS_END_PACK;
597 
598  static const uint16_t DEFAULT_WINDOW;
599 
600  template <typename T>
601  T generic_search(OptionTypes opt_type) const {
602  const option* opt = search_option(opt_type);
603  if (!opt) {
604  throw option_not_found();
605  }
606  return opt->to<T>();
607  }
608 
609  void write_serialization(uint8_t* buffer, uint32_t total_sz);
610  void checksum(uint16_t new_check);
611  uint32_t calculate_options_size() const;
612  uint32_t pad_options_size(uint32_t size) const;
613  options_type::const_iterator search_option_iterator(OptionTypes type) const;
614  options_type::iterator search_option_iterator(OptionTypes type);
615 
616  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
617 
618  options_type options_;
619  tcp_header header_;
620 };
621 
622 } // Tins
623 
624 #endif // TINS_TCP_H
uint16_t sport() const
Getter for the source port field.
Definition: tcp.h:188
Represents a TCP PDU.
Definition: tcp.h:76
OptionTypes
TCP options enum.
Definition: tcp.h:104
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
uint32_t seq() const
Getter for the sequence number field.
Definition: tcp.h:197
small_uint< 4 > data_offset() const
Getter for the data offset field.
Definition: tcp.h:242
uint16_t checksum() const
Getter for the checksum field.
Definition: tcp.h:224
std::vector< option > options_type
Definition: tcp.h:134
Represents a PDU option field.
Definition: pdu_option.h:201
void add_option(option &&opt)
Adds a TCP option.
Definition: tcp.h:479
PDUOption< uint8_t, TCP > option
Definition: tcp.h:129
TCP * clone() const
Definition: tcp.h:546
std::vector< uint32_t > sack_type
Definition: tcp.h:139
void add_option(Args &&...args)
Adds a TCP option using the provided arguments.
Definition: tcp.h:492
The Tins namespace.
Definition: address_range.h:38
T to() const
Constructs a T from this PDUOption.
Definition: pdu_option.h:389
uint32_t ack_seq() const
Getter for the acknowledge number field.
Definition: tcp.h:206
Type used to store a PDU header&#39;s data.
Definition: pdu.h:194
uint16_t urg_ptr() const
Getter for the urgent pointer field.
Definition: tcp.h:233
Flags
TCP flags enum.
Definition: tcp.h:88
uint16_t dport() const
Getter for the destination port field.
Definition: tcp.h:179
const options_type & options() const
Getter for the option list.
Definition: tcp.h:251
uint16_t window() const
Getter for the window size field.
Definition: tcp.h:215
AltChecksums
Alternate checksum enum.
Definition: tcp.h:120
Base class for protocol data units.
Definition: pdu.h:107
Exception thrown when an option is not found.
Definition: exceptions.h:56
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: tcp.h:532