libtins  4.0
ip.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_IP_H
31 #define TINS_IP_H
32 
33 #include <tins/pdu.h>
34 #include <tins/small_uint.h>
35 #include <tins/endianness.h>
36 #include <tins/ip_address.h>
37 #include <tins/pdu_option.h>
38 #include <tins/macros.h>
39 #include <tins/cxxstd.h>
40 
41 namespace Tins {
42 namespace Memory {
43 
44 class OutputMemoryStream;
45 
46 } // Memory
47 
63 class TINS_API IP : public PDU {
64 public:
68  static const PDU::PDUType pdu_flag = PDU::IP;
69 
74 
78  enum Flags {
79  FLAG_RESERVED = 4,
80  DONT_FRAGMENT = 2,
81  MORE_FRAGMENTS = 1
82  };
83 
90  enum OptionClass {
91  CONTROL = 0,
92  MEASUREMENT = 2
93  };
94 
101  END = 0,
102  NOOP = 1,
103  SEC = 2,
104  LSRR = 3,
105  TIMESTAMP = 4,
106  EXTSEC = 5,
107  RR = 7,
108  SID = 8,
109  SSRR = 9,
110  MTUPROBE = 11,
111  MTUREPLY = 12,
112  EIP = 17,
113  TR = 18,
114  ADDEXT = 19,
115  RTRALT = 20,
116  SDB = 21,
117  DPS = 23,
118  UMP = 24,
119  QS = 25
120  };
121 
125  TINS_BEGIN_PACK
127  #if TINS_IS_LITTLE_ENDIAN
128  uint8_t number:5,
129  op_class:2,
130  copied:1;
131  #elif TINS_IS_BIG_ENDIAN
132  uint8_t copied:1,
133  op_class:2,
134  number:5;
135  #endif
136 
142  #if TINS_IS_LITTLE_ENDIAN
143  : number(0), op_class(0), copied(0) {}
144  #else
145  : copied(0), op_class(0), number(0) {}
146  #endif
147 
157  option_identifier(uint8_t value)
158  #if TINS_IS_LITTLE_ENDIAN
159  : number(value & 0x1f),
160  op_class((value >> 5) & 0x03),
161  copied((value >> 7) & 0x01) {}
162  #elif TINS_IS_BIG_ENDIAN
163  : copied((value >> 7) & 0x01),
164  op_class((value >> 5) & 0x03),
165  number(value & 0x1f) {}
166  #endif
167 
174  option_identifier(OptionNumber number, OptionClass op_class,
175  small_uint<1> copied)
176  #if TINS_IS_LITTLE_ENDIAN
177  : number(number), op_class(op_class), copied(copied) {}
178  #else
179  : copied(copied), op_class(op_class), number(number) {}
180  #endif
181 
185  bool operator==(const option_identifier& rhs) const {
186  return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
187  }
188  } TINS_END_PACK;
189 
194 
198  struct security_type {
199  uint16_t security, compartments;
200  uint16_t handling_restrictions;
201  small_uint<24> transmission_control;
202 
203  security_type(uint16_t sec = 0,
204  uint16_t comp = 0,
205  uint16_t hand_res = 0,
206  small_uint<24> tcc = 0)
207  : security(sec), compartments(comp),
208  handling_restrictions(hand_res), transmission_control(tcc) { }
209 
210  static security_type from_option(const option& opt);
211  };
212 
217  typedef std::vector<address_type> routes_type;
218 
219  uint8_t pointer;
220  routes_type routes;
221 
222  generic_route_option_type(uint8_t ptr = 0, routes_type rts = routes_type())
223  : pointer(ptr), routes(rts) {}
224 
225  static generic_route_option_type from_option(const option& opt);
226  };
227 
232 
237 
242 
246  typedef std::vector<option> options_type;
247 
254  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
255 
266  IP(address_type ip_dst = address_type(),
267  address_type ip_src = address_type());
268 
280  IP(const uint8_t* buffer, uint32_t total_sz);
281 
282  /* Getters */
283 
290  return this->header_.ihl;
291  }
292 
298  uint8_t tos() const {
299  return header_.tos;
300  }
301 
307  uint16_t tot_len() const {
308  return Endian::be_to_host(header_.tot_len);
309  }
310 
316  uint16_t id() const {
317  return Endian::be_to_host(header_.id);
318  }
319 
330  TINS_DEPRECATED(uint16_t frag_off() const) {
331  return Endian::be_to_host(header_.frag_off);
332  }
333 
343  return Endian::be_to_host(header_.frag_off) & 0x1fff;
344  }
345 
351  Flags flags() const {
352  return static_cast<Flags>(Endian::be_to_host(header_.frag_off) >> 13);
353  }
354 
360  uint8_t ttl() const {
361  return header_.ttl;
362  }
363 
369  uint8_t protocol() const {
370  return header_.protocol;
371  }
372 
378  uint16_t checksum() const {
379  return Endian::be_to_host(header_.check);
380  }
381 
387  address_type src_addr() const {
388  return address_type(header_.saddr);
389  }
390 
395  address_type dst_addr() const {
396  return address_type(header_.daddr);
397  }
398 
404  return header_.version;
405  }
406 
411  const options_type& options() const {
412  return options_;
413  }
414 
415  /* Setters */
416 
422  void tos(uint8_t new_tos);
423 
429  void id(uint16_t new_id);
430 
441  TINS_DEPRECATED(void frag_off(uint16_t new_frag_off));
442 
452  void fragment_offset(small_uint<13> new_frag_off);
453 
459  void flags(Flags new_flags);
460 
466  void ttl(uint8_t new_ttl);
467 
484  void protocol(uint8_t new_protocol);
485 
491  void src_addr(address_type ip);
492 
498  void dst_addr(address_type ip);
499 
505  void version(small_uint<4> ver);
506 
515  void add_option(const option& opt);
516 
517  #if TINS_IS_CXX11
518 
525  void add_option(option &&opt) {
526  options_.push_back(std::move(opt));
527  }
528 
537  template<typename... Args>
538  void add_option(Args&&... args) {
539  options_.emplace_back(std::forward<Args>(args)...);
540  }
541  #endif
542 
552  bool remove_option(option_identifier id);
553 
563  const option* search_option(option_identifier id) const;
564 
565  // Option setters
566 
570  void eol();
571 
575  void noop();
576 
582  void security(const security_type& data);
583 
589  void lsrr(const lsrr_type& data) {
590  add_route_option(131, data);
591  }
592 
598  void ssrr(const ssrr_type& data) {
599  add_route_option(137, data);
600  }
601 
607  void record_route(const record_route_type& data) {
608  add_route_option(7, data);
609  }
610 
616  void stream_identifier(uint16_t stream_id);
617 
618  // Option getters
619 
628  security_type security() const;
629 
639  lsrr_type lsrr() const {
640  return search_route_option(131);
641  }
642 
652  ssrr_type ssrr() const {
653  return search_route_option(137);
654  }
655 
664  record_route_type record_route() const {
665  return search_route_option(7);
666  }
667 
676  uint16_t stream_identifier() const;
677 
678  /* Virtual methods */
679 
685  uint32_t header_size() const;
686 
690  void send(PacketSender& sender, const NetworkInterface &);
691 
699  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
700 
707  PDU* recv_response(PacketSender& sender, const NetworkInterface &);
708 
714  bool is_fragmented() const;
715 
720  PDUType pdu_type() const {
721  return pdu_flag;
722  }
723 
727  IP* clone() const {
728  return new IP(*this);
729  }
730 private:
731  static const uint8_t DEFAULT_TTL;
732 
733  TINS_BEGIN_PACK
734  struct ip_header {
735  #if TINS_IS_LITTLE_ENDIAN
736  uint8_t ihl:4,
737  version:4;
738  #else
739  uint8_t version:4,
740  ihl:4;
741  #endif
742  uint8_t tos;
743  uint16_t tot_len;
744  uint16_t id;
745  uint16_t frag_off;
746  uint8_t ttl;
747  uint8_t protocol;
748  uint16_t check;
749  uint32_t saddr;
750  uint32_t daddr;
751  } TINS_END_PACK;
752 
753  void head_len(small_uint<4> new_head_len);
754  void tot_len(uint16_t new_tot_len);
755 
756  void prepare_for_serialize();
757  uint32_t calculate_options_size() const;
758  uint32_t pad_options_size(uint32_t size) const;
759  void init_ip_fields();
760  void write_serialization(uint8_t* buffer, uint32_t total_sz);
761  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
762  void add_route_option(option_identifier id, const generic_route_option_type& data);
763  generic_route_option_type search_route_option(option_identifier id) const;
764  void checksum(uint16_t new_check);
765  options_type::const_iterator search_option_iterator(option_identifier id) const;
766  options_type::iterator search_option_iterator(option_identifier id);
767 
768  options_type options_;
769  ip_header header_;
770 };
771 
772 } // Tins
773 
774 #endif // TINS_IP_H
option_identifier()
Default constructor.
Definition: ip.h:141
address_type src_addr() const
Getter for the source address field.
Definition: ip.h:387
Flags flags() const
Getter for the flags field.
Definition: ip.h:351
Class that represents an IP PDU.
Definition: ip.h:63
generic_route_option_type lsrr_type
Definition: ip.h:231
generic_route_option_type ssrr_type
Definition: ip.h:236
PDUType pdu_type() const
Getter for the PDU&#39;s type.
Definition: ip.h:720
small_uint< 4 > head_len() const
Getter for the header length field.
Definition: ip.h:289
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:127
Flags
Definition: ip.h:78
void lsrr(const lsrr_type &data)
Adds a Loose Source and Record Route option.
Definition: ip.h:589
TINS_DEPRECATED(uint16_t frag_off() const)
Getter for the fragment offset field.
Definition: ip.h:330
PDUOption< option_identifier, IP > option
Definition: ip.h:193
lsrr_type lsrr() const
Searchs and returns a Loose Source and Record Route option.
Definition: ip.h:639
void ssrr(const ssrr_type &data)
Adds a Strict Source and Record Route option.
Definition: ip.h:598
uint16_t tot_len() const
Getter for the total length field.
Definition: ip.h:307
Sends packets through a network interface.
Definition: packet_sender.h:116
Represents a PDU option field.
Definition: pdu_option.h:201
const options_type & options() const
Getter for the IP options.
Definition: ip.h:411
IPv4Address address_type
Definition: ip.h:73
ssrr_type ssrr() const
Searchs and returns a Strict Source and Record Route option.
Definition: ip.h:652
IP * clone() const
Definition: ip.h:727
uint16_t id() const
Getter for the id field.
Definition: ip.h:316
OptionClass
Enum indicating the option&#39;s class.
Definition: ip.h:90
The Tins namespace.
Definition: address_range.h:38
Definition: ip.h:198
std::vector< option > options_type
Definition: ip.h:246
Type used to store a PDU header&#39;s data.
Definition: pdu.h:194
uint8_t tos() const
Getter for the type of service field.
Definition: ip.h:298
bool operator==(const option_identifier &rhs) const
Equality operator.
Definition: ip.h:185
Abstraction of a network interface.
Definition: network_interface.h:47
uint8_t protocol() const
Getter for the protocol field.
Definition: ip.h:369
Abstraction of an IPv4 address.
Definition: ip_address.h:45
address_type dst_addr() const
Getter for the destination address field.
Definition: ip.h:395
small_uint< 4 > version() const
Getter for the version field.
Definition: ip.h:403
small_uint< 13 > fragment_offset() const
Getter for the fragment offset field.
Definition: ip.h:342
void add_option(option &&opt)
Adds an IP option.
Definition: ip.h:525
generic_route_option_type record_route_type
Definition: ip.h:241
The type used to represent an option&#39;s type.
Definition: ip.h:126
void record_route(const record_route_type &data)
Adds a Record Route option.
Definition: ip.h:607
OptionNumber
Enum indicating the option&#39;s id number.
Definition: ip.h:100
uint16_t checksum() const
Getter for the checksum field.
Definition: ip.h:378
Base class for protocol data units.
Definition: pdu.h:107
void add_option(Args &&...args)
Adds an IP option.
Definition: ip.h:538
uint8_t ttl() const
Getter for the time to live field.
Definition: ip.h:360
record_route_type record_route() const
Searchs and returns a Record Route option.
Definition: ip.h:664