libtins  4.4
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 
313  bool has_flags(small_uint<12> check_flags) const;
314 
315  /* Setters */
316 
322  void dport(uint16_t new_dport);
323 
329  void sport(uint16_t new_sport);
330 
336  void seq(uint32_t new_seq);
337 
343  void ack_seq(uint32_t new_ack_seq);
344 
350  void window(uint16_t new_window);
351 
357  void urg_ptr(uint16_t new_urg_ptr);
358 
364  void data_offset(small_uint<4> new_doff);
365 
366  // Options
367 
373  void mss(uint16_t value);
374 
380  uint16_t mss() const;
381 
387  void winscale(uint8_t value);
388 
394  uint8_t winscale() const;
395 
399  void sack_permitted();
400 
405  bool has_sack_permitted() const;
406 
412  void sack(const sack_type& edges);
413 
419  sack_type sack() const;
420 
427  void timestamp(uint32_t value, uint32_t reply);
428 
435  std::pair<uint32_t, uint32_t> timestamp() const;
436 
442  void altchecksum(AltChecksums value);
443 
449  AltChecksums altchecksum() const;
450 
457  void set_flag(Flags tcp_flag, small_uint<1> value);
458 
477  void flags(small_uint<12> value);
478 
479 
485  void add_option(const option& opt);
486 
487  #if TINS_IS_CXX11
495  void add_option(option &&opt) {
496  options_.push_back(std::move(opt));
497  }
498 
507  template <typename... Args>
508  void add_option(Args&&... args) {
509  options_.emplace_back(std::forward<Args>(args)...);
510  }
511  #endif
512 
522  bool remove_option(OptionTypes type);
523 
532  uint32_t header_size() const;
533 
541  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
542 
548  PDUType pdu_type() const {
549  return pdu_flag;
550  }
551 
557  const option* search_option(OptionTypes type) const;
558 
562  TCP* clone() const {
563  return new TCP(*this);
564  }
565 private:
566  #if TINS_IS_LITTLE_ENDIAN
567  TINS_BEGIN_PACK
568  struct flags_type {
569  uint8_t fin:1,
570  syn:1,
571  rst:1,
572  psh:1,
573  ack:1,
574  urg:1,
575  ece:1,
576  cwr:1;
577  } TINS_END_PACK;
578  #else
579  TINS_BEGIN_PACK
580  struct flags_type {
581  uint8_t cwr:1,
582  ece:1,
583  urg:1,
584  ack:1,
585  psh:1,
586  rst:1,
587  syn:1,
588  fin:1;
589  } TINS_END_PACK;
590  #endif
591 
592  TINS_BEGIN_PACK
593  struct tcp_header {
594  uint16_t sport;
595  uint16_t dport;
596  uint32_t seq;
597  uint32_t ack_seq;
598  #if TINS_IS_LITTLE_ENDIAN
599  uint8_t res1:4,
600  doff:4;
601  #else
602  uint8_t doff:4,
603  res1:4;
604  #endif
605  union {
606  flags_type flags;
607  uint8_t flags_8;
608  };
609  uint16_t window;
610  uint16_t check;
611  uint16_t urg_ptr;
612  } TINS_END_PACK;
613 
614  static const uint16_t DEFAULT_WINDOW;
615 
616  template <typename T>
617  T generic_search(OptionTypes opt_type) const {
618  const option* opt = search_option(opt_type);
619  if (!opt) {
620  throw option_not_found();
621  }
622  return opt->to<T>();
623  }
624 
625  void write_serialization(uint8_t* buffer, uint32_t total_sz);
626  void checksum(uint16_t new_check);
627  uint32_t calculate_options_size() const;
628  uint32_t pad_options_size(uint32_t size) const;
629  options_type::const_iterator search_option_iterator(OptionTypes type) const;
630  options_type::iterator search_option_iterator(OptionTypes type);
631 
632  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
633 
634  options_type options_;
635  tcp_header header_;
636 };
637 
638 } // Tins
639 
640 #endif // TINS_TCP_H
Represents a PDU option field.
Definition: pdu_option.h:201
Base class for protocol data units.
Definition: pdu.h:107
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
Represents a TCP PDU.
Definition: tcp.h:76
PDUType pdu_type() const
Getter for the PDU's type.
Definition: tcp.h:548
uint16_t dport() const
Getter for the destination port field.
Definition: tcp.h:179
AltChecksums
Alternate checksum enum.
Definition: tcp.h:120
uint16_t sport() const
Getter for the source port field.
Definition: tcp.h:188
uint32_t ack_seq() const
Getter for the acknowledge number field.
Definition: tcp.h:206
uint32_t seq() const
Getter for the sequence number field.
Definition: tcp.h:197
OptionTypes
TCP options enum.
Definition: tcp.h:104
PDUOption< uint8_t, TCP > option
Definition: tcp.h:129
small_uint< 4 > data_offset() const
Getter for the data offset field.
Definition: tcp.h:242
Flags
TCP flags enum.
Definition: tcp.h:88
uint16_t checksum() const
Getter for the checksum field.
Definition: tcp.h:224
TCP * clone() const
Definition: tcp.h:562
uint16_t urg_ptr() const
Getter for the urgent pointer field.
Definition: tcp.h:233
uint16_t window() const
Getter for the window size field.
Definition: tcp.h:215
std::vector< option > options_type
Definition: tcp.h:134
void add_option(Args &&... args)
Adds a TCP option using the provided arguments.
Definition: tcp.h:508
const options_type & options() const
Getter for the option list.
Definition: tcp.h:251
void add_option(option &&opt)
Adds a TCP option.
Definition: tcp.h:495
std::vector< uint32_t > sack_type
Definition: tcp.h:139
The Tins namespace.
Definition: address_range.h:38
Type used to store a PDU header's data.
Definition: pdu.h:196