libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
ip.h
1 /*
2  * Copyright (c) 2016, 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 <list>
34 #include "pdu.h"
35 #include "small_uint.h"
36 #include "endianness.h"
37 #include "ip_address.h"
38 #include "pdu_option.h"
39 #include "macros.h"
40 #include "cxxstd.h"
41 
42 namespace Tins {
43 namespace Memory {
44 
45 class OutputMemoryStream;
46 
47 } // Memory
48 
64 class TINS_API IP : public PDU {
65 public:
69  static const PDU::PDUType pdu_flag = PDU::IP;
70 
75 
79  enum Flags {
80  FLAG_RESERVED = 4,
81  DONT_FRAGMENT = 2,
82  MORE_FRAGMENTS = 1
83  };
84 
91  enum OptionClass {
92  CONTROL = 0,
93  MEASUREMENT = 2
94  };
95 
102  END = 0,
103  NOOP = 1,
104  SEC = 2,
105  LSRR = 3,
106  TIMESTAMP = 4,
107  EXTSEC = 5,
108  RR = 7,
109  SID = 8,
110  SSRR = 9,
111  MTUPROBE = 11,
112  MTUREPLY = 12,
113  EIP = 17,
114  TR = 18,
115  ADDEXT = 19,
116  RTRALT = 20,
117  SDB = 21,
118  DPS = 23,
119  UMP = 24,
120  QS = 25
121  };
122 
126  TINS_BEGIN_PACK
128  #if TINS_IS_LITTLE_ENDIAN
129  uint8_t number:5,
130  op_class:2,
131  copied:1;
132  #elif TINS_IS_BIG_ENDIAN
133  uint8_t copied:1,
134  op_class:2,
135  number:5;
136  #endif
137 
143  #if TINS_IS_LITTLE_ENDIAN
144  : number(0), op_class(0), copied(0) {}
145  #else
146  : copied(0), op_class(0), number(0) {}
147  #endif
148 
158  option_identifier(uint8_t value)
159  #if TINS_IS_LITTLE_ENDIAN
160  : number(value & 0x1f),
161  op_class((value >> 5) & 0x03),
162  copied((value >> 7) & 0x01) {}
163  #elif TINS_IS_BIG_ENDIAN
164  : copied((value >> 7) & 0x01),
165  op_class((value >> 5) & 0x03),
166  number(value & 0x1f) {}
167  #endif
168 
176  small_uint<1> copied)
177  #if TINS_IS_LITTLE_ENDIAN
178  : number(number), op_class(op_class), copied(copied) {}
179  #else
180  : copied(copied), op_class(op_class), number(number) {}
181  #endif
182 
186  bool operator==(const option_identifier& rhs) const {
187  return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
188  }
189  } TINS_END_PACK;
190 
195 
199  struct security_type {
200  uint16_t security, compartments;
201  uint16_t handling_restrictions;
202  small_uint<24> transmission_control;
203 
204  security_type(uint16_t sec = 0,
205  uint16_t comp = 0,
206  uint16_t hand_res = 0,
207  small_uint<24> tcc = 0)
208  : security(sec), compartments(comp),
209  handling_restrictions(hand_res), transmission_control(tcc) { }
210 
211  static security_type from_option(const option& opt);
212  };
213 
218  typedef std::vector<address_type> routes_type;
219 
220  uint8_t pointer;
221  routes_type routes;
222 
223  generic_route_option_type(uint8_t ptr = 0, routes_type rts = routes_type())
224  : pointer(ptr), routes(rts) {}
225 
226  static generic_route_option_type from_option(const option& opt);
227  };
228 
233 
238 
243 
247  typedef std::list<option> options_type;
248 
255  static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
256 
267  IP(address_type ip_dst = address_type(),
268  address_type ip_src = address_type());
269 
281  IP(const uint8_t* buffer, uint32_t total_sz);
282 
283  /* Getters */
284 
291  return this->header_.ihl;
292  }
293 
299  uint8_t tos() const {
300  return header_.tos;
301  }
302 
308  uint16_t tot_len() const {
309  return Endian::be_to_host(header_.tot_len);
310  }
311 
317  uint16_t id() const {
318  return Endian::be_to_host(header_.id);
319  }
320 
331  TINS_DEPRECATED(uint16_t frag_off() const) {
332  return Endian::be_to_host(header_.frag_off);
333  }
334 
344  return Endian::be_to_host(header_.frag_off) & 0x1fff;
345  }
346 
352  Flags flags() const {
353  return static_cast<Flags>(Endian::be_to_host(header_.frag_off) >> 13);
354  }
355 
361  uint8_t ttl() const {
362  return header_.ttl;
363  }
364 
370  uint8_t protocol() const {
371  return header_.protocol;
372  }
373 
379  uint16_t checksum() const {
380  return Endian::be_to_host(header_.check);
381  }
382 
389  return address_type(header_.saddr);
390  }
391 
397  return address_type(header_.daddr);
398  }
399 
405  return header_.version;
406  }
407 
412  const options_type& options() const {
413  return ip_options_;
414  }
415 
416  /* Setters */
417 
423  void tos(uint8_t new_tos);
424 
430  void id(uint16_t new_id);
431 
442  TINS_DEPRECATED(void frag_off(uint16_t new_frag_off));
443 
453  void fragment_offset(small_uint<13> new_frag_off);
454 
460  void flags(Flags new_flags);
461 
467  void ttl(uint8_t new_ttl);
468 
485  void protocol(uint8_t new_protocol);
486 
492  void src_addr(address_type ip);
493 
499  void dst_addr(address_type ip);
500 
506  void version(small_uint<4> ver);
507 
516  void add_option(const option& opt);
517 
518  #if TINS_IS_CXX11
519 
526  void add_option(option &&opt) {
527  internal_add_option(opt);
528  ip_options_.push_back(std::move(opt));
529  }
530 
539  template<typename... Args>
540  void add_option(Args&&... args) {
541  ip_options_.emplace_back(std::forward<Args>(args)...);
542  internal_add_option(ip_options_.back());
543  }
544  #endif
545 
555  bool remove_option(option_identifier id);
556 
566  const option* search_option(option_identifier id) const;
567 
568  // Option setters
569 
573  void eol();
574 
578  void noop();
579 
585  void security(const security_type& data);
586 
592  void lsrr(const lsrr_type& data) {
593  add_route_option(131, data);
594  }
595 
601  void ssrr(const ssrr_type& data) {
602  add_route_option(137, data);
603  }
604 
610  void record_route(const record_route_type& data) {
611  add_route_option(7, data);
612  }
613 
619  void stream_identifier(uint16_t stream_id);
620 
621  // Option getters
622 
631  security_type security() const;
632 
642  lsrr_type lsrr() const {
643  return search_route_option(131);
644  }
645 
655  ssrr_type ssrr() const {
656  return search_route_option(137);
657  }
658 
668  return search_route_option(7);
669  }
670 
679  uint16_t stream_identifier() const;
680 
681  /* Virtual methods */
682 
688  uint32_t header_size() const;
689 
693  void send(PacketSender& sender, const NetworkInterface &);
694 
702  bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
703 
710  PDU* recv_response(PacketSender& sender, const NetworkInterface &);
711 
717  bool is_fragmented() const;
718 
723  PDUType pdu_type() const {
724  return pdu_flag;
725  }
726 
730  IP* clone() const {
731  return new IP(*this);
732  }
733 private:
734  static const uint8_t DEFAULT_TTL;
735 
736  TINS_BEGIN_PACK
737  struct ip_header {
738  #if TINS_IS_LITTLE_ENDIAN
739  uint8_t ihl:4,
740  version:4;
741  #else
742  uint8_t version:4,
743  ihl:4;
744  #endif
745  uint8_t tos;
746  uint16_t tot_len;
747  uint16_t id;
748  uint16_t frag_off;
749  uint8_t ttl;
750  uint8_t protocol;
751  uint16_t check;
752  uint32_t saddr;
753  uint32_t daddr;
754  } TINS_END_PACK;
755 
756  void head_len(small_uint<4> new_head_len);
757  void tot_len(uint16_t new_tot_len);
758 
759  void prepare_for_serialize(const PDU* parent);
760  void internal_add_option(const option& option);
761  void init_ip_fields();
762  void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent);
763  void write_option(const option& opt, Memory::OutputMemoryStream& stream);
764  void add_route_option(option_identifier id, const generic_route_option_type& data);
765  generic_route_option_type search_route_option(option_identifier id) const;
766  void checksum(uint16_t new_check);
767  options_type::const_iterator search_option_iterator(option_identifier id) const;
768  options_type::iterator search_option_iterator(option_identifier id);
769  void update_padded_options_size();
770 
771  ip_header header_;
772  uint16_t options_size_, padded_options_size_;
773  options_type ip_options_;
774 };
775 
776 } // Tins
777 
778 #endif // TINS_IP_H
option_identifier()
Default constructor.
Definition: ip.h:142
address_type src_addr() const
Getter for the source address field.
Definition: ip.h:388
Flags flags() const
Getter for the flags field.
Definition: ip.h:352
Class that represents an IP PDU.
Definition: ip.h:64
generic_route_option_type lsrr_type
Definition: ip.h:232
generic_route_option_type ssrr_type
Definition: ip.h:237
PDUType pdu_type() const
Getter for the PDU's type.
Definition: ip.h:723
small_uint< 4 > head_len() const
Getter for the header length field.
Definition: ip.h:290
PDUType
Enum which identifies each type of PDU.
Definition: pdu.h:128
Flags
Definition: ip.h:79
void lsrr(const lsrr_type &data)
Adds a Loose Source and Record Route option.
Definition: ip.h:592
TINS_DEPRECATED(uint16_t frag_off() const)
Getter for the fragment offset field.
Definition: ip.h:331
PDUOption< option_identifier, IP > option
Definition: ip.h:194
lsrr_type lsrr() const
Searchs and returns a Loose Source and Record Route option.
Definition: ip.h:642
void ssrr(const ssrr_type &data)
Adds a Strict Source and Record Route option.
Definition: ip.h:601
uint16_t tot_len() const
Getter for the total length field.
Definition: ip.h:308
Sends packets through a network interface.
Definition: packet_sender.h:117
Represents a PDU option field.
Definition: pdu_option.h:320
const options_type & options() const
Getter for the IP options.
Definition: ip.h:412
IPv4Address address_type
Definition: ip.h:74
std::list< option > options_type
Definition: ip.h:247
ssrr_type ssrr() const
Searchs and returns a Strict Source and Record Route option.
Definition: ip.h:655
IP * clone() const
Definition: ip.h:730
uint16_t id() const
Getter for the id field.
Definition: ip.h:317
OptionClass
Enum indicating the option's class.
Definition: ip.h:91
Definition: ip.h:199
Type used to store a PDU header's data.
Definition: pdu.h:195
option_identifier(OptionNumber number, OptionClass op_class, small_uint< 1 > copied)
Definition: ip.h:175
uint8_t tos() const
Getter for the type of service field.
Definition: ip.h:299
option_identifier(uint8_t value)
Constructs this option from a single uint8_t value.
Definition: ip.h:158
bool operator==(const option_identifier &rhs) const
Equality operator.
Definition: ip.h:186
Abstraction of a network interface.
Definition: network_interface.h:47
uint8_t protocol() const
Getter for the protocol field.
Definition: ip.h:370
Abstraction of an IPv4 address.
Definition: ip_address.h:44
address_type dst_addr() const
Getter for the destination address field.
Definition: ip.h:396
small_uint< 4 > version() const
Getter for the version field.
Definition: ip.h:404
small_uint< 13 > fragment_offset() const
Getter for the fragment offset field.
Definition: ip.h:343
void add_option(option &&opt)
Adds an IP option.
Definition: ip.h:526
generic_route_option_type record_route_type
Definition: ip.h:242
The type used to represent an option's type.
Definition: ip.h:127
void record_route(const record_route_type &data)
Adds a Record Route option.
Definition: ip.h:610
OptionNumber
Enum indicating the option's id number.
Definition: ip.h:101
uint16_t checksum() const
Getter for the checksum field.
Definition: ip.h:379
Base class for protocol data units.
Definition: pdu.h:108
void add_option(Args &&...args)
Adds an IP option.
Definition: ip.h:540
uint8_t ttl() const
Getter for the time to live field.
Definition: ip.h:361
record_route_type record_route() const
Searchs and returns a Record Route option.
Definition: ip.h:667